linux-loongson/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
Mohsin Bashir f2957147ae eth: fbnic: add support for TTI HW stats
Add coverage for the TX Extension (TEI) Interface (TTI) stats. We are
tracking packets and control message drops because of credit exhaustion
on the TX interface.

Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Mohsin Bashir <mohsin.bashr@gmail.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20250410070859.4160768-6-mohsin.bashr@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
2025-04-15 11:23:13 +02:00

552 lines
15 KiB
C

// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
#include "fbnic.h"
static void fbnic_hw_stat_rst32(struct fbnic_dev *fbd, u32 reg,
struct fbnic_stat_counter *stat)
{
/* We do not touch the "value" field here.
* It gets zeroed out on fbd structure allocation.
* After that we want it to grow continuously
* through device resets and power state changes.
*/
stat->u.old_reg_value_32 = rd32(fbd, reg);
}
static void fbnic_hw_stat_rd32(struct fbnic_dev *fbd, u32 reg,
struct fbnic_stat_counter *stat)
{
u32 new_reg_value;
new_reg_value = rd32(fbd, reg);
stat->value += new_reg_value - stat->u.old_reg_value_32;
stat->u.old_reg_value_32 = new_reg_value;
}
u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset)
{
u32 prev_upper, upper, lower, diff;
prev_upper = rd32(fbd, reg + offset);
lower = rd32(fbd, reg);
upper = rd32(fbd, reg + offset);
diff = upper - prev_upper;
if (!diff)
return ((u64)upper << 32) | lower;
if (diff > 1)
dev_warn_once(fbd->dev,
"Stats inconsistent, upper 32b of %#010x updating too quickly\n",
reg * 4);
/* Return only the upper bits as we cannot guarantee
* the accuracy of the lower bits. We will add them in
* when the counter slows down enough that we can get
* a snapshot with both upper values being the same
* between reads.
*/
return ((u64)upper << 32);
}
static void fbnic_hw_stat_rst64(struct fbnic_dev *fbd, u32 reg, s32 offset,
struct fbnic_stat_counter *stat)
{
/* Record initial counter values and compute deltas from there to ensure
* stats start at 0 after reboot/reset. This avoids exposing absolute
* hardware counter values to userspace.
*/
stat->u.old_reg_value_64 = fbnic_stat_rd64(fbd, reg, offset);
}
static void fbnic_hw_stat_rd64(struct fbnic_dev *fbd, u32 reg, s32 offset,
struct fbnic_stat_counter *stat)
{
u64 new_reg_value;
new_reg_value = fbnic_stat_rd64(fbd, reg, offset);
stat->value += new_reg_value - stat->u.old_reg_value_64;
stat->u.old_reg_value_64 = new_reg_value;
}
static void fbnic_reset_tmi_stats(struct fbnic_dev *fbd,
struct fbnic_tmi_stats *tmi)
{
fbnic_hw_stat_rst32(fbd, FBNIC_TMI_DROP_PKTS, &tmi->drop.frames);
fbnic_hw_stat_rst64(fbd, FBNIC_TMI_DROP_BYTE_L, 1, &tmi->drop.bytes);
fbnic_hw_stat_rst32(fbd,
FBNIC_TMI_ILLEGAL_PTP_REQS,
&tmi->ptp_illegal_req);
fbnic_hw_stat_rst32(fbd, FBNIC_TMI_GOOD_PTP_TS, &tmi->ptp_good_ts);
fbnic_hw_stat_rst32(fbd, FBNIC_TMI_BAD_PTP_TS, &tmi->ptp_bad_ts);
}
static void fbnic_get_tmi_stats32(struct fbnic_dev *fbd,
struct fbnic_tmi_stats *tmi)
{
fbnic_hw_stat_rd32(fbd, FBNIC_TMI_DROP_PKTS, &tmi->drop.frames);
fbnic_hw_stat_rd32(fbd,
FBNIC_TMI_ILLEGAL_PTP_REQS,
&tmi->ptp_illegal_req);
fbnic_hw_stat_rd32(fbd, FBNIC_TMI_GOOD_PTP_TS, &tmi->ptp_good_ts);
fbnic_hw_stat_rd32(fbd, FBNIC_TMI_BAD_PTP_TS, &tmi->ptp_bad_ts);
}
static void fbnic_get_tmi_stats(struct fbnic_dev *fbd,
struct fbnic_tmi_stats *tmi)
{
fbnic_hw_stat_rd64(fbd, FBNIC_TMI_DROP_BYTE_L, 1, &tmi->drop.bytes);
}
static void fbnic_reset_tti_stats(struct fbnic_dev *fbd,
struct fbnic_tti_stats *tti)
{
fbnic_hw_stat_rst32(fbd,
FBNIC_TCE_TTI_CM_DROP_PKTS,
&tti->cm_drop.frames);
fbnic_hw_stat_rst64(fbd,
FBNIC_TCE_TTI_CM_DROP_BYTE_L,
1,
&tti->cm_drop.bytes);
fbnic_hw_stat_rst32(fbd,
FBNIC_TCE_TTI_FRAME_DROP_PKTS,
&tti->frame_drop.frames);
fbnic_hw_stat_rst64(fbd,
FBNIC_TCE_TTI_FRAME_DROP_BYTE_L,
1,
&tti->frame_drop.bytes);
fbnic_hw_stat_rst32(fbd,
FBNIC_TCE_TBI_DROP_PKTS,
&tti->tbi_drop.frames);
fbnic_hw_stat_rst64(fbd,
FBNIC_TCE_TBI_DROP_BYTE_L,
1,
&tti->tbi_drop.bytes);
}
static void fbnic_get_tti_stats32(struct fbnic_dev *fbd,
struct fbnic_tti_stats *tti)
{
fbnic_hw_stat_rd32(fbd,
FBNIC_TCE_TTI_CM_DROP_PKTS,
&tti->cm_drop.frames);
fbnic_hw_stat_rd32(fbd,
FBNIC_TCE_TTI_FRAME_DROP_PKTS,
&tti->frame_drop.frames);
fbnic_hw_stat_rd32(fbd,
FBNIC_TCE_TBI_DROP_PKTS,
&tti->tbi_drop.frames);
}
static void fbnic_get_tti_stats(struct fbnic_dev *fbd,
struct fbnic_tti_stats *tti)
{
fbnic_hw_stat_rd64(fbd,
FBNIC_TCE_TTI_CM_DROP_BYTE_L,
1,
&tti->cm_drop.bytes);
fbnic_hw_stat_rd64(fbd,
FBNIC_TCE_TTI_FRAME_DROP_BYTE_L,
1,
&tti->frame_drop.bytes);
fbnic_hw_stat_rd64(fbd,
FBNIC_TCE_TBI_DROP_BYTE_L,
1,
&tti->tbi_drop.bytes);
}
static void fbnic_reset_rpc_stats(struct fbnic_dev *fbd,
struct fbnic_rpc_stats *rpc)
{
fbnic_hw_stat_rst32(fbd,
FBNIC_RPC_CNTR_UNKN_ETYPE,
&rpc->unkn_etype);
fbnic_hw_stat_rst32(fbd,
FBNIC_RPC_CNTR_UNKN_EXT_HDR,
&rpc->unkn_ext_hdr);
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV4_FRAG, &rpc->ipv4_frag);
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV6_FRAG, &rpc->ipv6_frag);
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV4_ESP, &rpc->ipv4_esp);
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV6_ESP, &rpc->ipv6_esp);
fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_TCP_OPT_ERR, &rpc->tcp_opt_err);
fbnic_hw_stat_rst32(fbd,
FBNIC_RPC_CNTR_OUT_OF_HDR_ERR,
&rpc->out_of_hdr_err);
fbnic_hw_stat_rst32(fbd,
FBNIC_RPC_CNTR_OVR_SIZE_ERR,
&rpc->ovr_size_err);
}
static void fbnic_get_rpc_stats32(struct fbnic_dev *fbd,
struct fbnic_rpc_stats *rpc)
{
fbnic_hw_stat_rd32(fbd,
FBNIC_RPC_CNTR_UNKN_ETYPE,
&rpc->unkn_etype);
fbnic_hw_stat_rd32(fbd,
FBNIC_RPC_CNTR_UNKN_EXT_HDR,
&rpc->unkn_ext_hdr);
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV4_FRAG, &rpc->ipv4_frag);
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV6_FRAG, &rpc->ipv6_frag);
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV4_ESP, &rpc->ipv4_esp);
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV6_ESP, &rpc->ipv6_esp);
fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_TCP_OPT_ERR, &rpc->tcp_opt_err);
fbnic_hw_stat_rd32(fbd,
FBNIC_RPC_CNTR_OUT_OF_HDR_ERR,
&rpc->out_of_hdr_err);
fbnic_hw_stat_rd32(fbd,
FBNIC_RPC_CNTR_OVR_SIZE_ERR,
&rpc->ovr_size_err);
}
static void fbnic_reset_rxb_fifo_stats(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_fifo_stats *fifo)
{
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_DROP_FRMS_STS(i),
&fifo->drop.frames);
fbnic_hw_stat_rst64(fbd, FBNIC_RXB_DROP_BYTES_STS_L(i), 1,
&fifo->drop.bytes);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRUN_FRMS_STS(i),
&fifo->trunc.frames);
fbnic_hw_stat_rst64(fbd, FBNIC_RXB_TRUN_BYTES_STS_L(i), 1,
&fifo->trunc.bytes);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRANS_DROP_STS(i),
&fifo->trans_drop);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRANS_ECN_STS(i),
&fifo->trans_ecn);
fifo->level.u.old_reg_value_32 = 0;
}
static void fbnic_reset_rxb_enq_stats(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_enqueue_stats *enq)
{
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_DRBO_FRM_CNT_SRC(i),
&enq->drbo.frames);
fbnic_hw_stat_rst64(fbd, FBNIC_RXB_DRBO_BYTE_CNT_SRC_L(i), 4,
&enq->drbo.bytes);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_INTEGRITY_ERR(i),
&enq->integrity_err);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_MAC_ERR(i),
&enq->mac_err);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_PARSER_ERR(i),
&enq->parser_err);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_FRM_ERR(i),
&enq->frm_err);
}
static void fbnic_reset_rxb_deq_stats(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_dequeue_stats *deq)
{
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_INTF_FRM_CNT_DST(i),
&deq->intf.frames);
fbnic_hw_stat_rst64(fbd, FBNIC_RXB_INTF_BYTE_CNT_DST_L(i), 4,
&deq->intf.bytes);
fbnic_hw_stat_rst32(fbd, FBNIC_RXB_PBUF_FRM_CNT_DST(i),
&deq->pbuf.frames);
fbnic_hw_stat_rst64(fbd, FBNIC_RXB_PBUF_BYTE_CNT_DST_L(i), 4,
&deq->pbuf.bytes);
}
static void fbnic_reset_rxb_stats(struct fbnic_dev *fbd,
struct fbnic_rxb_stats *rxb)
{
int i;
for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++)
fbnic_reset_rxb_fifo_stats(fbd, i, &rxb->fifo[i]);
for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) {
fbnic_reset_rxb_enq_stats(fbd, i, &rxb->enq[i]);
fbnic_reset_rxb_deq_stats(fbd, i, &rxb->deq[i]);
}
}
static void fbnic_get_rxb_fifo_stats32(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_fifo_stats *fifo)
{
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_DROP_FRMS_STS(i),
&fifo->drop.frames);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRUN_FRMS_STS(i),
&fifo->trunc.frames);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRANS_DROP_STS(i),
&fifo->trans_drop);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRANS_ECN_STS(i),
&fifo->trans_ecn);
fifo->level.value = rd32(fbd, FBNIC_RXB_PBUF_FIFO_LEVEL(i));
}
static void fbnic_get_rxb_fifo_stats(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_fifo_stats *fifo)
{
fbnic_hw_stat_rd64(fbd, FBNIC_RXB_DROP_BYTES_STS_L(i), 1,
&fifo->drop.bytes);
fbnic_hw_stat_rd64(fbd, FBNIC_RXB_TRUN_BYTES_STS_L(i), 1,
&fifo->trunc.bytes);
fbnic_get_rxb_fifo_stats32(fbd, i, fifo);
}
static void fbnic_get_rxb_enq_stats32(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_enqueue_stats *enq)
{
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_DRBO_FRM_CNT_SRC(i),
&enq->drbo.frames);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_INTEGRITY_ERR(i),
&enq->integrity_err);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_MAC_ERR(i),
&enq->mac_err);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_PARSER_ERR(i),
&enq->parser_err);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_FRM_ERR(i),
&enq->frm_err);
}
static void fbnic_get_rxb_enq_stats(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_enqueue_stats *enq)
{
fbnic_hw_stat_rd64(fbd, FBNIC_RXB_DRBO_BYTE_CNT_SRC_L(i), 4,
&enq->drbo.bytes);
fbnic_get_rxb_enq_stats32(fbd, i, enq);
}
static void fbnic_get_rxb_deq_stats32(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_dequeue_stats *deq)
{
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_INTF_FRM_CNT_DST(i),
&deq->intf.frames);
fbnic_hw_stat_rd32(fbd, FBNIC_RXB_PBUF_FRM_CNT_DST(i),
&deq->pbuf.frames);
}
static void fbnic_get_rxb_deq_stats(struct fbnic_dev *fbd, int i,
struct fbnic_rxb_dequeue_stats *deq)
{
fbnic_hw_stat_rd64(fbd, FBNIC_RXB_INTF_BYTE_CNT_DST_L(i), 4,
&deq->intf.bytes);
fbnic_hw_stat_rd64(fbd, FBNIC_RXB_PBUF_BYTE_CNT_DST_L(i), 4,
&deq->pbuf.bytes);
fbnic_get_rxb_deq_stats32(fbd, i, deq);
}
static void fbnic_get_rxb_stats32(struct fbnic_dev *fbd,
struct fbnic_rxb_stats *rxb)
{
int i;
for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++)
fbnic_get_rxb_fifo_stats32(fbd, i, &rxb->fifo[i]);
for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) {
fbnic_get_rxb_enq_stats32(fbd, i, &rxb->enq[i]);
fbnic_get_rxb_deq_stats32(fbd, i, &rxb->deq[i]);
}
}
static void fbnic_get_rxb_stats(struct fbnic_dev *fbd,
struct fbnic_rxb_stats *rxb)
{
int i;
for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++)
fbnic_get_rxb_fifo_stats(fbd, i, &rxb->fifo[i]);
for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) {
fbnic_get_rxb_enq_stats(fbd, i, &rxb->enq[i]);
fbnic_get_rxb_deq_stats(fbd, i, &rxb->deq[i]);
}
}
static void fbnic_reset_hw_rxq_stats(struct fbnic_dev *fbd,
struct fbnic_hw_q_stats *hw_q)
{
int i;
for (i = 0; i < fbd->max_num_queues; i++, hw_q++) {
u32 base = FBNIC_QUEUE(i);
fbnic_hw_stat_rst32(fbd,
base + FBNIC_QUEUE_RDE_PKT_ERR_CNT,
&hw_q->rde_pkt_err);
fbnic_hw_stat_rst32(fbd,
base + FBNIC_QUEUE_RDE_CQ_DROP_CNT,
&hw_q->rde_pkt_cq_drop);
fbnic_hw_stat_rst32(fbd,
base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT,
&hw_q->rde_pkt_bdq_drop);
}
}
static void fbnic_get_hw_rxq_stats32(struct fbnic_dev *fbd,
struct fbnic_hw_q_stats *hw_q)
{
int i;
for (i = 0; i < fbd->max_num_queues; i++, hw_q++) {
u32 base = FBNIC_QUEUE(i);
fbnic_hw_stat_rd32(fbd,
base + FBNIC_QUEUE_RDE_PKT_ERR_CNT,
&hw_q->rde_pkt_err);
fbnic_hw_stat_rd32(fbd,
base + FBNIC_QUEUE_RDE_CQ_DROP_CNT,
&hw_q->rde_pkt_cq_drop);
fbnic_hw_stat_rd32(fbd,
base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT,
&hw_q->rde_pkt_bdq_drop);
}
}
void fbnic_get_hw_q_stats(struct fbnic_dev *fbd,
struct fbnic_hw_q_stats *hw_q)
{
spin_lock(&fbd->hw_stats_lock);
fbnic_get_hw_rxq_stats32(fbd, hw_q);
spin_unlock(&fbd->hw_stats_lock);
}
static void fbnic_reset_pcie_stats_asic(struct fbnic_dev *fbd,
struct fbnic_pcie_stats *pcie)
{
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_RD_TLP_CNT_31_0,
1,
&pcie->ob_rd_tlp);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_RD_DWORD_CNT_31_0,
1,
&pcie->ob_rd_dword);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_CPL_TLP_CNT_31_0,
1,
&pcie->ob_cpl_tlp);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_CPL_DWORD_CNT_31_0,
1,
&pcie->ob_cpl_dword);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_WR_TLP_CNT_31_0,
1,
&pcie->ob_wr_tlp);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_WR_DWORD_CNT_31_0,
1,
&pcie->ob_wr_dword);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_RD_DBG_CNT_TAG_31_0,
1,
&pcie->ob_rd_no_tag);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_RD_DBG_CNT_CPL_CRED_31_0,
1,
&pcie->ob_rd_no_cpl_cred);
fbnic_hw_stat_rst64(fbd,
FBNIC_PUL_USER_OB_RD_DBG_CNT_NP_CRED_31_0,
1,
&pcie->ob_rd_no_np_cred);
}
static void fbnic_get_pcie_stats_asic64(struct fbnic_dev *fbd,
struct fbnic_pcie_stats *pcie)
{
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_RD_TLP_CNT_31_0,
1,
&pcie->ob_rd_tlp);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_RD_DWORD_CNT_31_0,
1,
&pcie->ob_rd_dword);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_WR_TLP_CNT_31_0,
1,
&pcie->ob_wr_tlp);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_WR_DWORD_CNT_31_0,
1,
&pcie->ob_wr_dword);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_CPL_TLP_CNT_31_0,
1,
&pcie->ob_cpl_tlp);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_CPL_DWORD_CNT_31_0,
1,
&pcie->ob_cpl_dword);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_RD_DBG_CNT_TAG_31_0,
1,
&pcie->ob_rd_no_tag);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_RD_DBG_CNT_CPL_CRED_31_0,
1,
&pcie->ob_rd_no_cpl_cred);
fbnic_hw_stat_rd64(fbd,
FBNIC_PUL_USER_OB_RD_DBG_CNT_NP_CRED_31_0,
1,
&pcie->ob_rd_no_np_cred);
}
void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
{
spin_lock(&fbd->hw_stats_lock);
fbnic_reset_tmi_stats(fbd, &fbd->hw_stats.tmi);
fbnic_reset_tti_stats(fbd, &fbd->hw_stats.tti);
fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc);
fbnic_reset_rxb_stats(fbd, &fbd->hw_stats.rxb);
fbnic_reset_hw_rxq_stats(fbd, fbd->hw_stats.hw_q);
fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie);
spin_unlock(&fbd->hw_stats_lock);
}
static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd)
{
fbnic_get_tmi_stats32(fbd, &fbd->hw_stats.tmi);
fbnic_get_tti_stats32(fbd, &fbd->hw_stats.tti);
fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc);
fbnic_get_rxb_stats32(fbd, &fbd->hw_stats.rxb);
fbnic_get_hw_rxq_stats32(fbd, fbd->hw_stats.hw_q);
}
void fbnic_get_hw_stats32(struct fbnic_dev *fbd)
{
spin_lock(&fbd->hw_stats_lock);
__fbnic_get_hw_stats32(fbd);
spin_unlock(&fbd->hw_stats_lock);
}
void fbnic_get_hw_stats(struct fbnic_dev *fbd)
{
spin_lock(&fbd->hw_stats_lock);
__fbnic_get_hw_stats32(fbd);
fbnic_get_tmi_stats(fbd, &fbd->hw_stats.tmi);
fbnic_get_tti_stats(fbd, &fbd->hw_stats.tti);
fbnic_get_rxb_stats(fbd, &fbd->hw_stats.rxb);
fbnic_get_pcie_stats_asic64(fbd, &fbd->hw_stats.pcie);
spin_unlock(&fbd->hw_stats_lock);
}