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

Merge branch 'cxgb4'

Hariprasad Shenai says:

====================
Add support to dump some hw debug info

This patch series adds support to dump sensor info, dump Transport Processor
event trace, dump Upper Layer Protocol RX module command trace, dump mailbox
contents and dump Transport Processor congestion control configuration.

Will send a separate patch series for all the hw stats patches, by moving them
to ethtool.

The patches series is created against 'net-next' tree.
And includes patches on cxgb4 driver.

We have included all the maintainers of respective drivers. Kindly review the
change and let us know in case of any review comments.

V2: Dopped all hw stats related patches. Added a new patch which adds support to
dump congestion control table.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+564
+5
drivers/net/ethernet/chelsio/cxgb4/cxgb4.h
··· 221 221 struct tp_params { 222 222 unsigned int ntxchan; /* # of Tx channels */ 223 223 unsigned int tre; /* log2 of core clocks per TP tick */ 224 + unsigned int la_mask; /* what events are recorded by TP LA */ 224 225 unsigned short tx_modq_map; /* TX modulation scheduler queue to */ 225 226 /* channel map */ 226 227 ··· 1173 1172 const char *t4_get_port_type_description(enum fw_port_type port_type); 1174 1173 void t4_get_port_stats(struct adapter *adap, int idx, struct port_stats *p); 1175 1174 void t4_read_mtu_tbl(struct adapter *adap, u16 *mtus, u8 *mtu_log); 1175 + void t4_read_cong_tbl(struct adapter *adap, u16 incr[NMTUS][NCCTRL_WIN]); 1176 1176 void t4_tp_wr_bits_indirect(struct adapter *adap, unsigned int addr, 1177 1177 unsigned int mask, unsigned int val); 1178 + void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr); 1178 1179 void t4_tp_get_tcp_stats(struct adapter *adap, struct tp_tcp_stats *v4, 1179 1180 struct tp_tcp_stats *v6); 1180 1181 void t4_load_mtus(struct adapter *adap, const unsigned short *mtus, 1181 1182 const unsigned short *alpha, const unsigned short *beta); 1183 + 1184 + void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf); 1182 1185 1183 1186 void t4_mk_filtdelwr(unsigned int ftid, struct fw_filter_wr *wr, int qid); 1184 1187
+433
drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c
··· 40 40 41 41 #include "cxgb4.h" 42 42 #include "t4_regs.h" 43 + #include "t4_values.h" 43 44 #include "t4fw_api.h" 44 45 #include "cxgb4_debugfs.h" 45 46 #include "clip_tbl.h" ··· 316 315 .release = seq_release_private 317 316 }; 318 317 318 + struct field_desc { 319 + const char *name; 320 + unsigned int start; 321 + unsigned int width; 322 + }; 323 + 324 + static void field_desc_show(struct seq_file *seq, u64 v, 325 + const struct field_desc *p) 326 + { 327 + char buf[32]; 328 + int line_size = 0; 329 + 330 + while (p->name) { 331 + u64 mask = (1ULL << p->width) - 1; 332 + int len = scnprintf(buf, sizeof(buf), "%s: %llu", p->name, 333 + ((unsigned long long)v >> p->start) & mask); 334 + 335 + if (line_size + len >= 79) { 336 + line_size = 8; 337 + seq_puts(seq, "\n "); 338 + } 339 + seq_printf(seq, "%s ", buf); 340 + line_size += len + 1; 341 + p++; 342 + } 343 + seq_putc(seq, '\n'); 344 + } 345 + 346 + static struct field_desc tp_la0[] = { 347 + { "RcfOpCodeOut", 60, 4 }, 348 + { "State", 56, 4 }, 349 + { "WcfState", 52, 4 }, 350 + { "RcfOpcSrcOut", 50, 2 }, 351 + { "CRxError", 49, 1 }, 352 + { "ERxError", 48, 1 }, 353 + { "SanityFailed", 47, 1 }, 354 + { "SpuriousMsg", 46, 1 }, 355 + { "FlushInputMsg", 45, 1 }, 356 + { "FlushInputCpl", 44, 1 }, 357 + { "RssUpBit", 43, 1 }, 358 + { "RssFilterHit", 42, 1 }, 359 + { "Tid", 32, 10 }, 360 + { "InitTcb", 31, 1 }, 361 + { "LineNumber", 24, 7 }, 362 + { "Emsg", 23, 1 }, 363 + { "EdataOut", 22, 1 }, 364 + { "Cmsg", 21, 1 }, 365 + { "CdataOut", 20, 1 }, 366 + { "EreadPdu", 19, 1 }, 367 + { "CreadPdu", 18, 1 }, 368 + { "TunnelPkt", 17, 1 }, 369 + { "RcfPeerFin", 16, 1 }, 370 + { "RcfReasonOut", 12, 4 }, 371 + { "TxCchannel", 10, 2 }, 372 + { "RcfTxChannel", 8, 2 }, 373 + { "RxEchannel", 6, 2 }, 374 + { "RcfRxChannel", 5, 1 }, 375 + { "RcfDataOutSrdy", 4, 1 }, 376 + { "RxDvld", 3, 1 }, 377 + { "RxOoDvld", 2, 1 }, 378 + { "RxCongestion", 1, 1 }, 379 + { "TxCongestion", 0, 1 }, 380 + { NULL } 381 + }; 382 + 383 + static int tp_la_show(struct seq_file *seq, void *v, int idx) 384 + { 385 + const u64 *p = v; 386 + 387 + field_desc_show(seq, *p, tp_la0); 388 + return 0; 389 + } 390 + 391 + static int tp_la_show2(struct seq_file *seq, void *v, int idx) 392 + { 393 + const u64 *p = v; 394 + 395 + if (idx) 396 + seq_putc(seq, '\n'); 397 + field_desc_show(seq, p[0], tp_la0); 398 + if (idx < (TPLA_SIZE / 2 - 1) || p[1] != ~0ULL) 399 + field_desc_show(seq, p[1], tp_la0); 400 + return 0; 401 + } 402 + 403 + static int tp_la_show3(struct seq_file *seq, void *v, int idx) 404 + { 405 + static struct field_desc tp_la1[] = { 406 + { "CplCmdIn", 56, 8 }, 407 + { "CplCmdOut", 48, 8 }, 408 + { "ESynOut", 47, 1 }, 409 + { "EAckOut", 46, 1 }, 410 + { "EFinOut", 45, 1 }, 411 + { "ERstOut", 44, 1 }, 412 + { "SynIn", 43, 1 }, 413 + { "AckIn", 42, 1 }, 414 + { "FinIn", 41, 1 }, 415 + { "RstIn", 40, 1 }, 416 + { "DataIn", 39, 1 }, 417 + { "DataInVld", 38, 1 }, 418 + { "PadIn", 37, 1 }, 419 + { "RxBufEmpty", 36, 1 }, 420 + { "RxDdp", 35, 1 }, 421 + { "RxFbCongestion", 34, 1 }, 422 + { "TxFbCongestion", 33, 1 }, 423 + { "TxPktSumSrdy", 32, 1 }, 424 + { "RcfUlpType", 28, 4 }, 425 + { "Eread", 27, 1 }, 426 + { "Ebypass", 26, 1 }, 427 + { "Esave", 25, 1 }, 428 + { "Static0", 24, 1 }, 429 + { "Cread", 23, 1 }, 430 + { "Cbypass", 22, 1 }, 431 + { "Csave", 21, 1 }, 432 + { "CPktOut", 20, 1 }, 433 + { "RxPagePoolFull", 18, 2 }, 434 + { "RxLpbkPkt", 17, 1 }, 435 + { "TxLpbkPkt", 16, 1 }, 436 + { "RxVfValid", 15, 1 }, 437 + { "SynLearned", 14, 1 }, 438 + { "SetDelEntry", 13, 1 }, 439 + { "SetInvEntry", 12, 1 }, 440 + { "CpcmdDvld", 11, 1 }, 441 + { "CpcmdSave", 10, 1 }, 442 + { "RxPstructsFull", 8, 2 }, 443 + { "EpcmdDvld", 7, 1 }, 444 + { "EpcmdFlush", 6, 1 }, 445 + { "EpcmdTrimPrefix", 5, 1 }, 446 + { "EpcmdTrimPostfix", 4, 1 }, 447 + { "ERssIp4Pkt", 3, 1 }, 448 + { "ERssIp6Pkt", 2, 1 }, 449 + { "ERssTcpUdpPkt", 1, 1 }, 450 + { "ERssFceFipPkt", 0, 1 }, 451 + { NULL } 452 + }; 453 + static struct field_desc tp_la2[] = { 454 + { "CplCmdIn", 56, 8 }, 455 + { "MpsVfVld", 55, 1 }, 456 + { "MpsPf", 52, 3 }, 457 + { "MpsVf", 44, 8 }, 458 + { "SynIn", 43, 1 }, 459 + { "AckIn", 42, 1 }, 460 + { "FinIn", 41, 1 }, 461 + { "RstIn", 40, 1 }, 462 + { "DataIn", 39, 1 }, 463 + { "DataInVld", 38, 1 }, 464 + { "PadIn", 37, 1 }, 465 + { "RxBufEmpty", 36, 1 }, 466 + { "RxDdp", 35, 1 }, 467 + { "RxFbCongestion", 34, 1 }, 468 + { "TxFbCongestion", 33, 1 }, 469 + { "TxPktSumSrdy", 32, 1 }, 470 + { "RcfUlpType", 28, 4 }, 471 + { "Eread", 27, 1 }, 472 + { "Ebypass", 26, 1 }, 473 + { "Esave", 25, 1 }, 474 + { "Static0", 24, 1 }, 475 + { "Cread", 23, 1 }, 476 + { "Cbypass", 22, 1 }, 477 + { "Csave", 21, 1 }, 478 + { "CPktOut", 20, 1 }, 479 + { "RxPagePoolFull", 18, 2 }, 480 + { "RxLpbkPkt", 17, 1 }, 481 + { "TxLpbkPkt", 16, 1 }, 482 + { "RxVfValid", 15, 1 }, 483 + { "SynLearned", 14, 1 }, 484 + { "SetDelEntry", 13, 1 }, 485 + { "SetInvEntry", 12, 1 }, 486 + { "CpcmdDvld", 11, 1 }, 487 + { "CpcmdSave", 10, 1 }, 488 + { "RxPstructsFull", 8, 2 }, 489 + { "EpcmdDvld", 7, 1 }, 490 + { "EpcmdFlush", 6, 1 }, 491 + { "EpcmdTrimPrefix", 5, 1 }, 492 + { "EpcmdTrimPostfix", 4, 1 }, 493 + { "ERssIp4Pkt", 3, 1 }, 494 + { "ERssIp6Pkt", 2, 1 }, 495 + { "ERssTcpUdpPkt", 1, 1 }, 496 + { "ERssFceFipPkt", 0, 1 }, 497 + { NULL } 498 + }; 499 + const u64 *p = v; 500 + 501 + if (idx) 502 + seq_putc(seq, '\n'); 503 + field_desc_show(seq, p[0], tp_la0); 504 + if (idx < (TPLA_SIZE / 2 - 1) || p[1] != ~0ULL) 505 + field_desc_show(seq, p[1], (p[0] & BIT(17)) ? tp_la2 : tp_la1); 506 + return 0; 507 + } 508 + 509 + static int tp_la_open(struct inode *inode, struct file *file) 510 + { 511 + struct seq_tab *p; 512 + struct adapter *adap = inode->i_private; 513 + 514 + switch (DBGLAMODE_G(t4_read_reg(adap, TP_DBG_LA_CONFIG_A))) { 515 + case 2: 516 + p = seq_open_tab(file, TPLA_SIZE / 2, 2 * sizeof(u64), 0, 517 + tp_la_show2); 518 + break; 519 + case 3: 520 + p = seq_open_tab(file, TPLA_SIZE / 2, 2 * sizeof(u64), 0, 521 + tp_la_show3); 522 + break; 523 + default: 524 + p = seq_open_tab(file, TPLA_SIZE, sizeof(u64), 0, tp_la_show); 525 + } 526 + if (!p) 527 + return -ENOMEM; 528 + 529 + t4_tp_read_la(adap, (u64 *)p->data, NULL); 530 + return 0; 531 + } 532 + 533 + static ssize_t tp_la_write(struct file *file, const char __user *buf, 534 + size_t count, loff_t *pos) 535 + { 536 + int err; 537 + char s[32]; 538 + unsigned long val; 539 + size_t size = min(sizeof(s) - 1, count); 540 + struct adapter *adap = FILE_DATA(file)->i_private; 541 + 542 + if (copy_from_user(s, buf, size)) 543 + return -EFAULT; 544 + s[size] = '\0'; 545 + err = kstrtoul(s, 0, &val); 546 + if (err) 547 + return err; 548 + if (val > 0xffff) 549 + return -EINVAL; 550 + adap->params.tp.la_mask = val << 16; 551 + t4_set_reg_field(adap, TP_DBG_LA_CONFIG_A, 0xffff0000U, 552 + adap->params.tp.la_mask); 553 + return count; 554 + } 555 + 556 + static const struct file_operations tp_la_fops = { 557 + .owner = THIS_MODULE, 558 + .open = tp_la_open, 559 + .read = seq_read, 560 + .llseek = seq_lseek, 561 + .release = seq_release_private, 562 + .write = tp_la_write 563 + }; 564 + 565 + static int ulprx_la_show(struct seq_file *seq, void *v, int idx) 566 + { 567 + const u32 *p = v; 568 + 569 + if (v == SEQ_START_TOKEN) 570 + seq_puts(seq, " Pcmd Type Message" 571 + " Data\n"); 572 + else 573 + seq_printf(seq, "%08x%08x %4x %08x %08x%08x%08x%08x\n", 574 + p[1], p[0], p[2], p[3], p[7], p[6], p[5], p[4]); 575 + return 0; 576 + } 577 + 578 + static int ulprx_la_open(struct inode *inode, struct file *file) 579 + { 580 + struct seq_tab *p; 581 + struct adapter *adap = inode->i_private; 582 + 583 + p = seq_open_tab(file, ULPRX_LA_SIZE, 8 * sizeof(u32), 1, 584 + ulprx_la_show); 585 + if (!p) 586 + return -ENOMEM; 587 + 588 + t4_ulprx_read_la(adap, (u32 *)p->data); 589 + return 0; 590 + } 591 + 592 + static const struct file_operations ulprx_la_fops = { 593 + .owner = THIS_MODULE, 594 + .open = ulprx_la_open, 595 + .read = seq_read, 596 + .llseek = seq_lseek, 597 + .release = seq_release_private 598 + }; 599 + 319 600 /* Show the PM memory stats. These stats include: 320 601 * 321 602 * TX: ··· 662 379 .release = single_release, 663 380 .write = pm_stats_clear 664 381 }; 382 + 383 + static int cctrl_tbl_show(struct seq_file *seq, void *v) 384 + { 385 + static const char * const dec_fac[] = { 386 + "0.5", "0.5625", "0.625", "0.6875", "0.75", "0.8125", "0.875", 387 + "0.9375" }; 388 + 389 + int i; 390 + u16 incr[NMTUS][NCCTRL_WIN]; 391 + struct adapter *adap = seq->private; 392 + 393 + t4_read_cong_tbl(adap, incr); 394 + 395 + for (i = 0; i < NCCTRL_WIN; ++i) { 396 + seq_printf(seq, "%2d: %4u %4u %4u %4u %4u %4u %4u %4u\n", i, 397 + incr[0][i], incr[1][i], incr[2][i], incr[3][i], 398 + incr[4][i], incr[5][i], incr[6][i], incr[7][i]); 399 + seq_printf(seq, "%8u %4u %4u %4u %4u %4u %4u %4u %5u %s\n", 400 + incr[8][i], incr[9][i], incr[10][i], incr[11][i], 401 + incr[12][i], incr[13][i], incr[14][i], incr[15][i], 402 + adap->params.a_wnd[i], 403 + dec_fac[adap->params.b_wnd[i]]); 404 + } 405 + return 0; 406 + } 407 + 408 + DEFINE_SIMPLE_DEBUGFS_FILE(cctrl_tbl); 665 409 666 410 /* Format a value in a unit that differs from the value's native unit by the 667 411 * given factor. ··· 948 638 .release = seq_release_private 949 639 }; 950 640 641 + static int mbox_show(struct seq_file *seq, void *v) 642 + { 643 + static const char * const owner[] = { "none", "FW", "driver", 644 + "unknown" }; 645 + 646 + int i; 647 + unsigned int mbox = (uintptr_t)seq->private & 7; 648 + struct adapter *adap = seq->private - mbox; 649 + void __iomem *addr = adap->regs + PF_REG(mbox, CIM_PF_MAILBOX_DATA_A); 650 + unsigned int ctrl_reg = (is_t4(adap->params.chip) 651 + ? CIM_PF_MAILBOX_CTRL_A 652 + : CIM_PF_MAILBOX_CTRL_SHADOW_COPY_A); 653 + void __iomem *ctrl = adap->regs + PF_REG(mbox, ctrl_reg); 654 + 655 + i = MBOWNER_G(readl(ctrl)); 656 + seq_printf(seq, "mailbox owned by %s\n\n", owner[i]); 657 + 658 + for (i = 0; i < MBOX_LEN; i += 8) 659 + seq_printf(seq, "%016llx\n", 660 + (unsigned long long)readq(addr + i)); 661 + return 0; 662 + } 663 + 664 + static int mbox_open(struct inode *inode, struct file *file) 665 + { 666 + return single_open(file, mbox_show, inode->i_private); 667 + } 668 + 669 + static ssize_t mbox_write(struct file *file, const char __user *buf, 670 + size_t count, loff_t *pos) 671 + { 672 + int i; 673 + char c = '\n', s[256]; 674 + unsigned long long data[8]; 675 + const struct inode *ino; 676 + unsigned int mbox; 677 + struct adapter *adap; 678 + void __iomem *addr; 679 + void __iomem *ctrl; 680 + 681 + if (count > sizeof(s) - 1 || !count) 682 + return -EINVAL; 683 + if (copy_from_user(s, buf, count)) 684 + return -EFAULT; 685 + s[count] = '\0'; 686 + 687 + if (sscanf(s, "%llx %llx %llx %llx %llx %llx %llx %llx%c", &data[0], 688 + &data[1], &data[2], &data[3], &data[4], &data[5], &data[6], 689 + &data[7], &c) < 8 || c != '\n') 690 + return -EINVAL; 691 + 692 + ino = FILE_DATA(file); 693 + mbox = (uintptr_t)ino->i_private & 7; 694 + adap = ino->i_private - mbox; 695 + addr = adap->regs + PF_REG(mbox, CIM_PF_MAILBOX_DATA_A); 696 + ctrl = addr + MBOX_LEN; 697 + 698 + if (MBOWNER_G(readl(ctrl)) != X_MBOWNER_PL) 699 + return -EBUSY; 700 + 701 + for (i = 0; i < 8; i++) 702 + writeq(data[i], addr + 8 * i); 703 + 704 + writel(MBMSGVALID_F | MBOWNER_V(X_MBOWNER_FW), ctrl); 705 + return count; 706 + } 707 + 708 + static const struct file_operations mbox_debugfs_fops = { 709 + .owner = THIS_MODULE, 710 + .open = mbox_open, 711 + .read = seq_read, 712 + .llseek = seq_lseek, 713 + .release = single_release, 714 + .write = mbox_write 715 + }; 716 + 951 717 static ssize_t flash_read(struct file *file, char __user *buf, size_t count, 952 718 loff_t *ppos) 953 719 { ··· 1198 812 .llseek = seq_lseek, 1199 813 .release = seq_release, 1200 814 }; 815 + 816 + /* Display various sensor information. 817 + */ 818 + static int sensors_show(struct seq_file *seq, void *v) 819 + { 820 + struct adapter *adap = seq->private; 821 + u32 param[7], val[7]; 822 + int ret; 823 + 824 + /* Note that if the sensors haven't been initialized and turned on 825 + * we'll get values of 0, so treat those as "<unknown>" ... 826 + */ 827 + param[0] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | 828 + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) | 829 + FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_TMP)); 830 + param[1] = (FW_PARAMS_MNEM_V(FW_PARAMS_MNEM_DEV) | 831 + FW_PARAMS_PARAM_X_V(FW_PARAMS_PARAM_DEV_DIAG) | 832 + FW_PARAMS_PARAM_Y_V(FW_PARAM_DEV_DIAG_VDD)); 833 + ret = t4_query_params(adap, adap->mbox, adap->fn, 0, 2, 834 + param, val); 835 + 836 + if (ret < 0 || val[0] == 0) 837 + seq_puts(seq, "Temperature: <unknown>\n"); 838 + else 839 + seq_printf(seq, "Temperature: %dC\n", val[0]); 840 + 841 + if (ret < 0 || val[1] == 0) 842 + seq_puts(seq, "Core VDD: <unknown>\n"); 843 + else 844 + seq_printf(seq, "Core VDD: %dmV\n", val[1]); 845 + 846 + return 0; 847 + } 848 + 849 + DEFINE_SIMPLE_DEBUGFS_FILE(sensors); 1201 850 1202 851 #if IS_ENABLED(CONFIG_IPV6) 1203 852 static int clip_tbl_open(struct inode *inode, struct file *file) ··· 1985 1564 { "cim_qcfg", &cim_qcfg_fops, S_IRUSR, 0 }, 1986 1565 { "clk", &clk_debugfs_fops, S_IRUSR, 0 }, 1987 1566 { "devlog", &devlog_fops, S_IRUSR, 0 }, 1567 + { "mbox0", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 0 }, 1568 + { "mbox1", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 1 }, 1569 + { "mbox2", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 2 }, 1570 + { "mbox3", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 3 }, 1571 + { "mbox4", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 4 }, 1572 + { "mbox5", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 5 }, 1573 + { "mbox6", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 6 }, 1574 + { "mbox7", &mbox_debugfs_fops, S_IRUSR | S_IWUSR, 7 }, 1988 1575 { "l2t", &t4_l2t_fops, S_IRUSR, 0}, 1989 1576 { "mps_tcam", &mps_tcam_debugfs_fops, S_IRUSR, 0 }, 1990 1577 { "rss", &rss_debugfs_fops, S_IRUSR, 0 }, ··· 2013 1584 { "obq_ulp3", &cim_obq_fops, S_IRUSR, 3 }, 2014 1585 { "obq_sge", &cim_obq_fops, S_IRUSR, 4 }, 2015 1586 { "obq_ncsi", &cim_obq_fops, S_IRUSR, 5 }, 1587 + { "tp_la", &tp_la_fops, S_IRUSR, 0 }, 1588 + { "ulprx_la", &ulprx_la_fops, S_IRUSR, 0 }, 1589 + { "sensors", &sensors_debugfs_fops, S_IRUSR, 0 }, 2016 1590 { "pm_stats", &pm_stats_debugfs_fops, S_IRUSR, 0 }, 1591 + { "cctrl", &cctrl_tbl_debugfs_fops, S_IRUSR, 0 }, 2017 1592 #if IS_ENABLED(CONFIG_IPV6) 2018 1593 { "clip_tbl", &clip_tbl_debugfs_fops, S_IRUSR, 0 }, 2019 1594 #endif
+83
drivers/net/ethernet/chelsio/cxgb4/t4_hw.c
··· 1263 1263 return t4_wr_mbox(adap, adap->mbox, &c, sizeof(c), NULL); 1264 1264 } 1265 1265 1266 + void t4_ulprx_read_la(struct adapter *adap, u32 *la_buf) 1267 + { 1268 + unsigned int i, j; 1269 + 1270 + for (i = 0; i < 8; i++) { 1271 + u32 *p = la_buf + i; 1272 + 1273 + t4_write_reg(adap, ULP_RX_LA_CTL_A, i); 1274 + j = t4_read_reg(adap, ULP_RX_LA_WRPTR_A); 1275 + t4_write_reg(adap, ULP_RX_LA_RDPTR_A, j); 1276 + for (j = 0; j < ULPRX_LA_SIZE; j++, p += 8) 1277 + *p = t4_read_reg(adap, ULP_RX_LA_RDDATA_A); 1278 + } 1279 + } 1280 + 1266 1281 #define ADVERT_MASK (FW_PORT_CAP_SPEED_100M | FW_PORT_CAP_SPEED_1G |\ 1267 1282 FW_PORT_CAP_SPEED_10G | FW_PORT_CAP_SPEED_40G | \ 1268 1283 FW_PORT_CAP_ANEG) ··· 2416 2401 if (mtu_log) 2417 2402 mtu_log[i] = MTUWIDTH_G(v); 2418 2403 } 2404 + } 2405 + 2406 + /** 2407 + * t4_read_cong_tbl - reads the congestion control table 2408 + * @adap: the adapter 2409 + * @incr: where to store the alpha values 2410 + * 2411 + * Reads the additive increments programmed into the HW congestion 2412 + * control table. 2413 + */ 2414 + void t4_read_cong_tbl(struct adapter *adap, u16 incr[NMTUS][NCCTRL_WIN]) 2415 + { 2416 + unsigned int mtu, w; 2417 + 2418 + for (mtu = 0; mtu < NMTUS; ++mtu) 2419 + for (w = 0; w < NCCTRL_WIN; ++w) { 2420 + t4_write_reg(adap, TP_CCTRL_TABLE_A, 2421 + ROWINDEX_V(0xffff) | (mtu << 5) | w); 2422 + incr[mtu][w] = (u16)t4_read_reg(adap, 2423 + TP_CCTRL_TABLE_A) & 0x1fff; 2424 + } 2419 2425 } 2420 2426 2421 2427 /** ··· 4817 4781 ret = r; 4818 4782 } 4819 4783 return ret; 4784 + } 4785 + 4786 + /** 4787 + * t4_tp_read_la - read TP LA capture buffer 4788 + * @adap: the adapter 4789 + * @la_buf: where to store the LA data 4790 + * @wrptr: the HW write pointer within the capture buffer 4791 + * 4792 + * Reads the contents of the TP LA buffer with the most recent entry at 4793 + * the end of the returned data and with the entry at @wrptr first. 4794 + * We leave the LA in the running state we find it in. 4795 + */ 4796 + void t4_tp_read_la(struct adapter *adap, u64 *la_buf, unsigned int *wrptr) 4797 + { 4798 + bool last_incomplete; 4799 + unsigned int i, cfg, val, idx; 4800 + 4801 + cfg = t4_read_reg(adap, TP_DBG_LA_CONFIG_A) & 0xffff; 4802 + if (cfg & DBGLAENABLE_F) /* freeze LA */ 4803 + t4_write_reg(adap, TP_DBG_LA_CONFIG_A, 4804 + adap->params.tp.la_mask | (cfg ^ DBGLAENABLE_F)); 4805 + 4806 + val = t4_read_reg(adap, TP_DBG_LA_CONFIG_A); 4807 + idx = DBGLAWPTR_G(val); 4808 + last_incomplete = DBGLAMODE_G(val) >= 2 && (val & DBGLAWHLF_F) == 0; 4809 + if (last_incomplete) 4810 + idx = (idx + 1) & DBGLARPTR_M; 4811 + if (wrptr) 4812 + *wrptr = idx; 4813 + 4814 + val &= 0xffff; 4815 + val &= ~DBGLARPTR_V(DBGLARPTR_M); 4816 + val |= adap->params.tp.la_mask; 4817 + 4818 + for (i = 0; i < TPLA_SIZE; i++) { 4819 + t4_write_reg(adap, TP_DBG_LA_CONFIG_A, DBGLARPTR_V(idx) | val); 4820 + la_buf[i] = t4_read_reg64(adap, TP_DBG_LA_DATAL_A); 4821 + idx = (idx + 1) & DBGLARPTR_M; 4822 + } 4823 + 4824 + /* Wipe out last entry if it isn't valid */ 4825 + if (last_incomplete) 4826 + la_buf[TPLA_SIZE - 1] = ~0ULL; 4827 + 4828 + if (cfg & DBGLAENABLE_F) /* restore running state */ 4829 + t4_write_reg(adap, TP_DBG_LA_CONFIG_A, 4830 + cfg | adap->params.tp.la_mask); 4820 4831 }
+2
drivers/net/ethernet/chelsio/cxgb4/t4_hw.h
··· 63 63 CIMLA_SIZE = 2048, /* # of 32-bit words in CIM LA */ 64 64 CIM_IBQ_SIZE = 128, /* # of 128-bit words in a CIM IBQ */ 65 65 CIM_OBQ_SIZE = 128, /* # of 128-bit words in a CIM OBQ */ 66 + TPLA_SIZE = 128, /* # of 64-bit words in TP LA */ 67 + ULPRX_LA_SIZE = 512, /* # of 256-bit words in ULP_RX LA */ 66 68 }; 67 69 68 70 enum {
+30
drivers/net/ethernet/chelsio/cxgb4/t4_regs.h
··· 947 947 948 948 /* registers for module CIM */ 949 949 #define CIM_BOOT_CFG_A 0x7b00 950 + #define CIM_PF_MAILBOX_CTRL_SHADOW_COPY_A 0x290 950 951 951 952 #define BOOTADDR_M 0xffffff00U 952 953 ··· 1184 1183 #define RSVDSPACEINT_F RSVDSPACEINT_V(1U) 1185 1184 1186 1185 /* registers for module TP */ 1186 + #define DBGLAWHLF_S 23 1187 + #define DBGLAWHLF_V(x) ((x) << DBGLAWHLF_S) 1188 + #define DBGLAWHLF_F DBGLAWHLF_V(1U) 1189 + 1190 + #define DBGLAWPTR_S 16 1191 + #define DBGLAWPTR_M 0x7fU 1192 + #define DBGLAWPTR_G(x) (((x) >> DBGLAWPTR_S) & DBGLAWPTR_M) 1193 + 1194 + #define DBGLAENABLE_S 12 1195 + #define DBGLAENABLE_V(x) ((x) << DBGLAENABLE_S) 1196 + #define DBGLAENABLE_F DBGLAENABLE_V(1U) 1197 + 1198 + #define DBGLARPTR_S 0 1199 + #define DBGLARPTR_M 0x7fU 1200 + #define DBGLARPTR_V(x) ((x) << DBGLARPTR_S) 1201 + 1202 + #define TP_DBG_LA_DATAL_A 0x7ed8 1203 + #define TP_DBG_LA_CONFIG_A 0x7ed4 1187 1204 #define TP_OUT_CONFIG_A 0x7d04 1188 1205 #define TP_GLOBAL_CONFIG_A 0x7d08 1206 + 1207 + #define DBGLAMODE_S 14 1208 + #define DBGLAMODE_M 0x3U 1209 + #define DBGLAMODE_G(x) (((x) >> DBGLAMODE_S) & DBGLAMODE_M) 1189 1210 1190 1211 #define FIVETUPLELOOKUP_S 17 1191 1212 #define FIVETUPLELOOKUP_M 0x3U ··· 1291 1268 #define KEEPALIVEMAXR2_M 0xfU 1292 1269 #define KEEPALIVEMAXR2_V(x) ((x) << KEEPALIVEMAXR2_S) 1293 1270 #define KEEPALIVEMAXR2_G(x) (((x) >> KEEPALIVEMAXR2_S) & KEEPALIVEMAXR2_M) 1271 + 1272 + #define ROWINDEX_S 16 1273 + #define ROWINDEX_V(x) ((x) << ROWINDEX_S) 1294 1274 1295 1275 #define TP_CCTRL_TABLE_A 0x7ddc 1296 1276 #define TP_MTU_TABLE_A 0x7de4 ··· 2274 2248 #define ULP_RX_INT_CAUSE_A 0x19158 2275 2249 #define ULP_RX_ISCSI_TAGMASK_A 0x19164 2276 2250 #define ULP_RX_ISCSI_PSZ_A 0x19168 2251 + #define ULP_RX_LA_CTL_A 0x1923c 2252 + #define ULP_RX_LA_RDPTR_A 0x19240 2253 + #define ULP_RX_LA_RDDATA_A 0x19244 2254 + #define ULP_RX_LA_WRPTR_A 0x19248 2277 2255 2278 2256 #define HPZ3_S 24 2279 2257 #define HPZ3_V(x) ((x) << HPZ3_S)
+5
drivers/net/ethernet/chelsio/cxgb4/t4_values.h
··· 79 79 #define SGE_UDB_GTS 20 80 80 #define SGE_UDB_WCDOORBELL 64 81 81 82 + /* CIM register field values. 83 + */ 84 + #define X_MBOWNER_FW 1 85 + #define X_MBOWNER_PL 2 86 + 82 87 /* PCI-E definitions */ 83 88 #define WINDOW_SHIFT_X 10 84 89 #define PCIEOFST_SHIFT_X 10
+6
drivers/net/ethernet/chelsio/cxgb4/t4fw_api.h
··· 1059 1059 FW_PARAMS_PARAM_DEV_FWREV = 0x0B, 1060 1060 FW_PARAMS_PARAM_DEV_TPREV = 0x0C, 1061 1061 FW_PARAMS_PARAM_DEV_CF = 0x0D, 1062 + FW_PARAMS_PARAM_DEV_DIAG = 0x11, 1062 1063 FW_PARAMS_PARAM_DEV_MAXORDIRD_QP = 0x13, /* max supported QP IRD/ORD */ 1063 1064 FW_PARAMS_PARAM_DEV_MAXIRD_ADAPTER = 0x14, /* max supported adap IRD */ 1064 1065 FW_PARAMS_PARAM_DEV_ULPTX_MEMWRITE_DSGL = 0x17, ··· 1121 1120 FW_PARAMS_PARAM_DMAQ_EQ_CMPLIQID_CTRL = 0x11, 1122 1121 FW_PARAMS_PARAM_DMAQ_EQ_SCHEDCLASS_ETH = 0x12, 1123 1122 FW_PARAMS_PARAM_DMAQ_EQ_DCBPRIO_ETH = 0x13, 1123 + }; 1124 + 1125 + enum fw_params_param_dev_diag { 1126 + FW_PARAM_DEV_DIAG_TMP = 0x00, 1127 + FW_PARAM_DEV_DIAG_VDD = 0x01, 1124 1128 }; 1125 1129 1126 1130 enum fw_params_param_dev_fwcache {