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

Merge branch 'eth-fbnic-extend-hw-stats-support'

Jakub Kicinski says:

====================
eth: fbnic: Extend hw stats support

Mohsin says:

Extend hardware stats support for fbnic by adding the ability to reset
hardware stats when the device experience a reset due to a PCI error and
include MAC stats in the hardware stats reset. Additionally, expand
hardware stats coverage to include FEC, PHY, and Pause stats.

v1: https://lore.kernel.org/20250822164731.1461754-1-kuba@kernel.org
====================

Link: https://patch.msgid.link/20250825200206.2357713-1-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

+240 -21
-3
drivers/net/ethernet/meta/fbnic/fbnic.h
··· 84 84 /* Local copy of hardware statistics */ 85 85 struct fbnic_hw_stats hw_stats; 86 86 87 - /* Lock protecting access to hw_stats */ 88 - spinlock_t hw_stats_lock; 89 - 90 87 struct fbnic_fw_log fw_log; 91 88 }; 92 89
+19
drivers/net/ethernet/meta/fbnic/fbnic_csr.h
··· 790 790 #define FBNIC_CSR_END_PCS 0x10668 /* CSR section delimiter */ 791 791 792 792 #define FBNIC_CSR_START_RSFEC 0x10800 /* CSR section delimiter */ 793 + 794 + /* We have 4 RSFEC engines present in our part, however we are only using 1. 795 + * As such only CCW(0) and NCCW(0) will never be non-zero and the other 796 + * registers can be ignored. 797 + */ 798 + #define FBNIC_RSFEC_CCW_LO(n) (0x10802 + 8 * (n)) /* 0x42008 + 32*n */ 799 + #define FBNIC_RSFEC_CCW_HI(n) (0x10803 + 8 * (n)) /* 0x4200c + 32*n */ 800 + #define FBNIC_RSFEC_NCCW_LO(n) (0x10804 + 8 * (n)) /* 0x42010 + 32*n */ 801 + #define FBNIC_RSFEC_NCCW_HI(n) (0x10805 + 8 * (n)) /* 0x42014 + 32*n */ 802 + 803 + #define FBNIC_PCS_MAX_LANES 4 804 + #define FBNIC_PCS_SYMBLERR_LO(n) \ 805 + (0x10880 + 2 * (n)) /* 0x42200 + 8*n */ 806 + #define FBNIC_PCS_SYMBLERR_HI(n) \ 807 + (0x10881 + 2 * (n)) /* 0x42204 + 8*n */ 793 808 #define FBNIC_CSR_END_RSFEC 0x108c8 /* CSR section delimiter */ 794 809 795 810 /* MAC MAC registers (ASIC only) */ ··· 844 829 #define FBNIC_CSR_END_SIG 0x1184e /* CSR section delimiter */ 845 830 846 831 #define FBNIC_CSR_START_MAC_STAT 0x11a00 832 + #define FBNIC_MAC_STAT_RX_XOFF_STB_L 0x11a00 /* 0x46800 */ 833 + #define FBNIC_MAC_STAT_RX_XOFF_STB_H 0x11a01 /* 0x46804 */ 834 + #define FBNIC_MAC_STAT_TX_XOFF_STB_L 0x11a04 /* 0x46810 */ 835 + #define FBNIC_MAC_STAT_TX_XOFF_STB_H 0x11a05 /* 0x46814 */ 847 836 #define FBNIC_MAC_STAT_RX_BYTE_COUNT_L 0x11a08 /* 0x46820 */ 848 837 #define FBNIC_MAC_STAT_RX_BYTE_COUNT_H 0x11a09 /* 0x46824 */ 849 838 #define FBNIC_MAC_STAT_RX_ALIGN_ERROR_L 0x11a0a /* 0x46828 */
+61 -2
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
··· 518 518 519 519 fbnic_get_hw_stats(fbn->fbd); 520 520 521 - spin_lock(&fbd->hw_stats_lock); 521 + spin_lock(&fbd->hw_stats.lock); 522 522 fbnic_report_hw_stats(fbnic_gstrings_hw_stats, &fbd->hw_stats, 523 523 FBNIC_HW_FIXED_STATS_LEN, &data); 524 524 ··· 555 555 fbnic_report_hw_stats(fbnic_gstrings_hw_q_stats, hw_q, 556 556 FBNIC_HW_Q_STATS_LEN, &data); 557 557 } 558 - spin_unlock(&fbd->hw_stats_lock); 558 + spin_unlock(&fbd->hw_stats.lock); 559 559 560 560 for (i = 0; i < FBNIC_MAX_XDPQS; i++) 561 561 fbnic_get_xdp_queue_stats(fbn->tx[i + FBNIC_MAX_TXQS], &data); ··· 1642 1642 } 1643 1643 1644 1644 static void 1645 + fbnic_get_pause_stats(struct net_device *netdev, 1646 + struct ethtool_pause_stats *pause_stats) 1647 + { 1648 + struct fbnic_net *fbn = netdev_priv(netdev); 1649 + struct fbnic_mac_stats *mac_stats; 1650 + struct fbnic_dev *fbd = fbn->fbd; 1651 + 1652 + mac_stats = &fbd->hw_stats.mac; 1653 + 1654 + fbd->mac->get_pause_stats(fbd, false, &mac_stats->pause); 1655 + 1656 + pause_stats->tx_pause_frames = mac_stats->pause.tx_pause_frames.value; 1657 + pause_stats->rx_pause_frames = mac_stats->pause.rx_pause_frames.value; 1658 + } 1659 + 1660 + static void 1661 + fbnic_get_fec_stats(struct net_device *netdev, 1662 + struct ethtool_fec_stats *fec_stats) 1663 + { 1664 + struct fbnic_net *fbn = netdev_priv(netdev); 1665 + struct fbnic_phy_stats *phy_stats; 1666 + struct fbnic_dev *fbd = fbn->fbd; 1667 + 1668 + fbnic_get_hw_stats32(fbd); 1669 + phy_stats = &fbd->hw_stats.phy; 1670 + 1671 + spin_lock(&fbd->hw_stats.lock); 1672 + fec_stats->corrected_blocks.total = 1673 + phy_stats->fec.corrected_blocks.value; 1674 + fec_stats->uncorrectable_blocks.total = 1675 + phy_stats->fec.uncorrectable_blocks.value; 1676 + spin_unlock(&fbd->hw_stats.lock); 1677 + } 1678 + 1679 + static void 1680 + fbnic_get_eth_phy_stats(struct net_device *netdev, 1681 + struct ethtool_eth_phy_stats *eth_phy_stats) 1682 + { 1683 + struct fbnic_net *fbn = netdev_priv(netdev); 1684 + struct fbnic_phy_stats *phy_stats; 1685 + struct fbnic_dev *fbd = fbn->fbd; 1686 + u64 total = 0; 1687 + int i; 1688 + 1689 + fbnic_get_hw_stats32(fbd); 1690 + phy_stats = &fbd->hw_stats.phy; 1691 + 1692 + spin_lock(&fbd->hw_stats.lock); 1693 + for (i = 0; i < FBNIC_PCS_MAX_LANES; i++) 1694 + total += phy_stats->pcs.SymbolErrorDuringCarrier.lanes[i].value; 1695 + 1696 + eth_phy_stats->SymbolErrorDuringCarrier = total; 1697 + spin_unlock(&fbd->hw_stats.lock); 1698 + } 1699 + 1700 + static void 1645 1701 fbnic_get_eth_mac_stats(struct net_device *netdev, 1646 1702 struct ethtool_eth_mac_stats *eth_mac_stats) 1647 1703 { ··· 1817 1761 .set_coalesce = fbnic_set_coalesce, 1818 1762 .get_ringparam = fbnic_get_ringparam, 1819 1763 .set_ringparam = fbnic_set_ringparam, 1764 + .get_pause_stats = fbnic_get_pause_stats, 1820 1765 .get_pauseparam = fbnic_phylink_get_pauseparam, 1821 1766 .set_pauseparam = fbnic_phylink_set_pauseparam, 1822 1767 .get_strings = fbnic_get_strings, ··· 1839 1782 .get_ts_info = fbnic_get_ts_info, 1840 1783 .get_ts_stats = fbnic_get_ts_stats, 1841 1784 .get_link_ksettings = fbnic_phylink_ethtool_ksettings_get, 1785 + .get_fec_stats = fbnic_get_fec_stats, 1842 1786 .get_fecparam = fbnic_phylink_get_fecparam, 1787 + .get_eth_phy_stats = fbnic_get_eth_phy_stats, 1843 1788 .get_eth_mac_stats = fbnic_get_eth_mac_stats, 1844 1789 .get_eth_ctrl_stats = fbnic_get_eth_ctrl_stats, 1845 1790 .get_rmon_stats = fbnic_get_rmon_stats,
+58 -8
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0 2 2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */ 3 3 4 + #include <linux/rtnetlink.h> 5 + 4 6 #include "fbnic.h" 5 7 6 8 static void fbnic_hw_stat_rst32(struct fbnic_dev *fbd, u32 reg, ··· 423 421 void fbnic_get_hw_q_stats(struct fbnic_dev *fbd, 424 422 struct fbnic_hw_q_stats *hw_q) 425 423 { 426 - spin_lock(&fbd->hw_stats_lock); 424 + spin_lock(&fbd->hw_stats.lock); 427 425 fbnic_get_hw_rxq_stats32(fbd, hw_q); 428 - spin_unlock(&fbd->hw_stats_lock); 426 + spin_unlock(&fbd->hw_stats.lock); 429 427 } 430 428 431 429 static void fbnic_reset_pcie_stats_asic(struct fbnic_dev *fbd, ··· 512 510 &pcie->ob_rd_no_np_cred); 513 511 } 514 512 513 + static void fbnic_reset_phy_stats(struct fbnic_dev *fbd, 514 + struct fbnic_phy_stats *phy_stats) 515 + { 516 + const struct fbnic_mac *mac = fbd->mac; 517 + 518 + mac->get_fec_stats(fbd, true, &phy_stats->fec); 519 + mac->get_pcs_stats(fbd, true, &phy_stats->pcs); 520 + } 521 + 522 + static void fbnic_get_phy_stats32(struct fbnic_dev *fbd, 523 + struct fbnic_phy_stats *phy_stats) 524 + { 525 + const struct fbnic_mac *mac = fbd->mac; 526 + 527 + mac->get_fec_stats(fbd, false, &phy_stats->fec); 528 + mac->get_pcs_stats(fbd, false, &phy_stats->pcs); 529 + } 530 + 531 + static void fbnic_reset_hw_mac_stats(struct fbnic_dev *fbd, 532 + struct fbnic_mac_stats *mac_stats) 533 + { 534 + const struct fbnic_mac *mac = fbd->mac; 535 + 536 + mac->get_eth_mac_stats(fbd, true, &mac_stats->eth_mac); 537 + mac->get_pause_stats(fbd, true, &mac_stats->pause); 538 + mac->get_eth_ctrl_stats(fbd, true, &mac_stats->eth_ctrl); 539 + mac->get_rmon_stats(fbd, true, &mac_stats->rmon); 540 + } 541 + 515 542 void fbnic_reset_hw_stats(struct fbnic_dev *fbd) 516 543 { 517 - spin_lock(&fbd->hw_stats_lock); 544 + spin_lock(&fbd->hw_stats.lock); 545 + fbnic_reset_phy_stats(fbd, &fbd->hw_stats.phy); 518 546 fbnic_reset_tmi_stats(fbd, &fbd->hw_stats.tmi); 519 547 fbnic_reset_tti_stats(fbd, &fbd->hw_stats.tti); 520 548 fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc); 521 549 fbnic_reset_rxb_stats(fbd, &fbd->hw_stats.rxb); 522 550 fbnic_reset_hw_rxq_stats(fbd, fbd->hw_stats.hw_q); 523 551 fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie); 524 - spin_unlock(&fbd->hw_stats_lock); 552 + spin_unlock(&fbd->hw_stats.lock); 553 + 554 + /* Once registered, the only other access to MAC stats is via the 555 + * ethtool API which is protected by the rtnl_lock. The call to 556 + * fbnic_reset_hw_stats() during PCI recovery is also protected 557 + * by the rtnl_lock hence, we don't need the spinlock to access 558 + * the MAC stats. 559 + */ 560 + if (fbd->netdev) 561 + ASSERT_RTNL(); 562 + fbnic_reset_hw_mac_stats(fbd, &fbd->hw_stats.mac); 563 + } 564 + 565 + void fbnic_init_hw_stats(struct fbnic_dev *fbd) 566 + { 567 + spin_lock_init(&fbd->hw_stats.lock); 568 + 569 + fbnic_reset_hw_stats(fbd); 525 570 } 526 571 527 572 static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd) 528 573 { 574 + fbnic_get_phy_stats32(fbd, &fbd->hw_stats.phy); 529 575 fbnic_get_tmi_stats32(fbd, &fbd->hw_stats.tmi); 530 576 fbnic_get_tti_stats32(fbd, &fbd->hw_stats.tti); 531 577 fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc); ··· 583 533 584 534 void fbnic_get_hw_stats32(struct fbnic_dev *fbd) 585 535 { 586 - spin_lock(&fbd->hw_stats_lock); 536 + spin_lock(&fbd->hw_stats.lock); 587 537 __fbnic_get_hw_stats32(fbd); 588 - spin_unlock(&fbd->hw_stats_lock); 538 + spin_unlock(&fbd->hw_stats.lock); 589 539 } 590 540 591 541 void fbnic_get_hw_stats(struct fbnic_dev *fbd) 592 542 { 593 - spin_lock(&fbd->hw_stats_lock); 543 + spin_lock(&fbd->hw_stats.lock); 594 544 __fbnic_get_hw_stats32(fbd); 595 545 596 546 fbnic_get_tmi_stats(fbd, &fbd->hw_stats.tmi); 597 547 fbnic_get_tti_stats(fbd, &fbd->hw_stats.tti); 598 548 fbnic_get_rxb_stats(fbd, &fbd->hw_stats.rxb); 599 549 fbnic_get_pcie_stats_asic64(fbd, &fbd->hw_stats.pcie); 600 - spin_unlock(&fbd->hw_stats_lock); 550 + spin_unlock(&fbd->hw_stats.lock); 601 551 }
+28
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
··· 5 5 #define _FBNIC_HW_STATS_H_ 6 6 7 7 #include <linux/ethtool.h> 8 + #include <linux/spinlock.h> 8 9 9 10 #include "fbnic_csr.h" 10 11 ··· 21 20 struct fbnic_hw_stat { 22 21 struct fbnic_stat_counter frames; 23 22 struct fbnic_stat_counter bytes; 23 + }; 24 + 25 + struct fbnic_fec_stats { 26 + struct fbnic_stat_counter corrected_blocks, uncorrectable_blocks; 27 + }; 28 + 29 + struct fbnic_pcs_stats { 30 + struct { 31 + struct fbnic_stat_counter lanes[FBNIC_PCS_MAX_LANES]; 32 + } SymbolErrorDuringCarrier; 24 33 }; 25 34 26 35 /* Note: not updated by fbnic_get_hw_stats() */ ··· 50 39 struct fbnic_stat_counter hist_tx[ETHTOOL_RMON_HIST_MAX]; 51 40 }; 52 41 42 + /* Note: not updated by fbnic_get_hw_stats() */ 43 + struct fbnic_pause_stats { 44 + struct fbnic_stat_counter tx_pause_frames; 45 + struct fbnic_stat_counter rx_pause_frames; 46 + }; 47 + 53 48 struct fbnic_eth_mac_stats { 54 49 struct fbnic_stat_counter FramesTransmittedOK; 55 50 struct fbnic_stat_counter FramesReceivedOK; ··· 72 55 struct fbnic_stat_counter FrameTooLongErrors; 73 56 }; 74 57 58 + struct fbnic_phy_stats { 59 + struct fbnic_fec_stats fec; 60 + struct fbnic_pcs_stats pcs; 61 + }; 62 + 75 63 struct fbnic_mac_stats { 76 64 struct fbnic_eth_mac_stats eth_mac; 65 + struct fbnic_pause_stats pause; 77 66 struct fbnic_eth_ctrl_stats eth_ctrl; 78 67 struct fbnic_rmon_stats rmon; 79 68 }; ··· 138 115 }; 139 116 140 117 struct fbnic_hw_stats { 118 + struct fbnic_phy_stats phy; 141 119 struct fbnic_mac_stats mac; 142 120 struct fbnic_tmi_stats tmi; 143 121 struct fbnic_tti_stats tti; ··· 146 122 struct fbnic_rxb_stats rxb; 147 123 struct fbnic_hw_q_stats hw_q[FBNIC_MAX_QUEUES]; 148 124 struct fbnic_pcie_stats pcie; 125 + 126 + /* Lock protecting the access to hw stats */ 127 + spinlock_t lock; 149 128 }; 150 129 151 130 u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset); 152 131 153 132 void fbnic_reset_hw_stats(struct fbnic_dev *fbd); 133 + void fbnic_init_hw_stats(struct fbnic_dev *fbd); 154 134 void fbnic_get_hw_q_stats(struct fbnic_dev *fbd, 155 135 struct fbnic_hw_q_stats *hw_q); 156 136 void fbnic_get_hw_stats32(struct fbnic_dev *fbd);
+57
drivers/net/ethernet/meta/fbnic/fbnic_mac.c
··· 632 632 } 633 633 634 634 static void 635 + fbnic_pcs_rsfec_stat_rd32(struct fbnic_dev *fbd, u32 reg, bool reset, 636 + struct fbnic_stat_counter *stat) 637 + { 638 + u32 pcs_rsfec_stat; 639 + 640 + /* The PCS/RFSEC registers are only 16b wide each. So what we will 641 + * have after the 64b read is 0x0000xxxx0000xxxx. To make it usable 642 + * as a full stat we will shift the upper bits into the lower set of 643 + * 0s and then mask off the math at 32b. 644 + * 645 + * Read ordering must be lower reg followed by upper reg. 646 + */ 647 + pcs_rsfec_stat = rd32(fbd, reg) & 0xffff; 648 + pcs_rsfec_stat |= rd32(fbd, reg + 1) << 16; 649 + 650 + /* RFSEC registers clear themselves upon being read so there is no 651 + * need to store the old_reg_value. 652 + */ 653 + if (!reset) 654 + stat->value += pcs_rsfec_stat; 655 + } 656 + 657 + static void 658 + fbnic_mac_get_fec_stats(struct fbnic_dev *fbd, bool reset, 659 + struct fbnic_fec_stats *s) 660 + { 661 + fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_CCW_LO(0), reset, 662 + &s->corrected_blocks); 663 + fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_RSFEC_NCCW_LO(0), reset, 664 + &s->uncorrectable_blocks); 665 + } 666 + 667 + static void 668 + fbnic_mac_get_pcs_stats(struct fbnic_dev *fbd, bool reset, 669 + struct fbnic_pcs_stats *s) 670 + { 671 + int i; 672 + 673 + for (i = 0; i < FBNIC_PCS_MAX_LANES; i++) 674 + fbnic_pcs_rsfec_stat_rd32(fbd, FBNIC_PCS_SYMBLERR_LO(i), reset, 675 + &s->SymbolErrorDuringCarrier.lanes[i]); 676 + } 677 + 678 + static void 635 679 fbnic_mac_get_eth_mac_stats(struct fbnic_dev *fbd, bool reset, 636 680 struct fbnic_eth_mac_stats *mac_stats) 637 681 { ··· 707 663 MAC_STAT_TX_MULTICAST); 708 664 fbnic_mac_stat_rd64(fbd, reset, mac_stats->BroadcastFramesXmittedOK, 709 665 MAC_STAT_TX_BROADCAST); 666 + } 667 + 668 + static void 669 + fbnic_mac_get_pause_stats(struct fbnic_dev *fbd, bool reset, 670 + struct fbnic_pause_stats *pause_stats) 671 + { 672 + fbnic_mac_stat_rd64(fbd, reset, pause_stats->tx_pause_frames, 673 + MAC_STAT_TX_XOFF_STB); 674 + fbnic_mac_stat_rd64(fbd, reset, pause_stats->rx_pause_frames, 675 + MAC_STAT_RX_XOFF_STB); 710 676 } 711 677 712 678 static void ··· 863 809 .pcs_disable = fbnic_pcs_disable_asic, 864 810 .pcs_get_link = fbnic_pcs_get_link_asic, 865 811 .pcs_get_link_event = fbnic_pcs_get_link_event_asic, 812 + .get_fec_stats = fbnic_mac_get_fec_stats, 813 + .get_pcs_stats = fbnic_mac_get_pcs_stats, 866 814 .get_eth_mac_stats = fbnic_mac_get_eth_mac_stats, 815 + .get_pause_stats = fbnic_mac_get_pause_stats, 867 816 .get_eth_ctrl_stats = fbnic_mac_get_eth_ctrl_stats, 868 817 .get_rmon_stats = fbnic_mac_get_rmon_stats, 869 818 .link_down = fbnic_mac_link_down_asic,
+6
drivers/net/ethernet/meta/fbnic/fbnic_mac.h
··· 79 79 bool (*pcs_get_link)(struct fbnic_dev *fbd); 80 80 int (*pcs_get_link_event)(struct fbnic_dev *fbd); 81 81 82 + void (*get_fec_stats)(struct fbnic_dev *fbd, bool reset, 83 + struct fbnic_fec_stats *fec_stats); 84 + void (*get_pcs_stats)(struct fbnic_dev *fbd, bool reset, 85 + struct fbnic_pcs_stats *pcs_stats); 82 86 void (*get_eth_mac_stats)(struct fbnic_dev *fbd, bool reset, 83 87 struct fbnic_eth_mac_stats *mac_stats); 88 + void (*get_pause_stats)(struct fbnic_dev *fbd, bool reset, 89 + struct fbnic_pause_stats *pause_stats); 84 90 void (*get_eth_ctrl_stats)(struct fbnic_dev *fbd, bool reset, 85 91 struct fbnic_eth_ctrl_stats *ctrl_stats); 86 92 void (*get_rmon_stats)(struct fbnic_dev *fbd, bool reset,
+6 -6
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
··· 424 424 tx_dropped = stats->dropped; 425 425 426 426 /* Record drops from Tx HW Datapath */ 427 - spin_lock(&fbd->hw_stats_lock); 427 + spin_lock(&fbd->hw_stats.lock); 428 428 tx_dropped += fbd->hw_stats.tmi.drop.frames.value + 429 429 fbd->hw_stats.tti.cm_drop.frames.value + 430 430 fbd->hw_stats.tti.frame_drop.frames.value + 431 431 fbd->hw_stats.tti.tbi_drop.frames.value; 432 - spin_unlock(&fbd->hw_stats_lock); 432 + spin_unlock(&fbd->hw_stats.lock); 433 433 434 434 stats64->tx_bytes = tx_bytes; 435 435 stats64->tx_packets = tx_packets; ··· 460 460 rx_packets = stats->packets; 461 461 rx_dropped = stats->dropped; 462 462 463 - spin_lock(&fbd->hw_stats_lock); 463 + spin_lock(&fbd->hw_stats.lock); 464 464 /* Record drops for the host FIFOs. 465 465 * 4: network to Host, 6: BMC to Host 466 466 * Exclude the BMC and MC FIFOs as those stats may contain drops ··· 480 480 /* Report packets with errors */ 481 481 rx_errors += fbd->hw_stats.hw_q[i].rde_pkt_err.value; 482 482 } 483 - spin_unlock(&fbd->hw_stats_lock); 483 + spin_unlock(&fbd->hw_stats.lock); 484 484 485 485 stats64->rx_bytes = rx_bytes; 486 486 stats64->rx_packets = rx_packets; ··· 608 608 609 609 fbnic_get_hw_q_stats(fbd, fbd->hw_stats.hw_q); 610 610 611 - spin_lock(&fbd->hw_stats_lock); 611 + spin_lock(&fbd->hw_stats.lock); 612 612 rx->hw_drop_overruns = fbd->hw_stats.hw_q[idx].rde_pkt_cq_drop.value + 613 613 fbd->hw_stats.hw_q[idx].rde_pkt_bdq_drop.value; 614 614 rx->hw_drops = fbd->hw_stats.hw_q[idx].rde_pkt_err.value + 615 615 rx->hw_drop_overruns; 616 - spin_unlock(&fbd->hw_stats_lock); 616 + spin_unlock(&fbd->hw_stats.lock); 617 617 } 618 618 619 619 static void fbnic_get_queue_stats_tx(struct net_device *dev, int idx,
+5 -2
drivers/net/ethernet/meta/fbnic/fbnic_pci.c
··· 304 304 305 305 fbnic_devlink_register(fbd); 306 306 fbnic_dbg_fbd_init(fbd); 307 - spin_lock_init(&fbd->hw_stats_lock); 308 307 309 308 /* Capture snapshot of hardware stats so netdev can calculate delta */ 310 - fbnic_reset_hw_stats(fbd); 309 + fbnic_init_hw_stats(fbd); 311 310 312 311 fbnic_hwmon_register(fbd); 313 312 ··· 490 491 struct fbnic_dev *fbd = dev_get_drvdata(dev); 491 492 struct net_device *netdev = fbd->netdev; 492 493 struct fbnic_net *fbn; 494 + 495 + rtnl_lock(); 496 + fbnic_reset_hw_stats(fbd); 497 + rtnl_unlock(); 493 498 494 499 if (fbnic_init_failure(fbd)) 495 500 return;