1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
6 static void fbnic_hw_stat_rst32(struct fbnic_dev
*fbd
, u32 reg
,
7 struct fbnic_stat_counter
*stat
)
9 /* We do not touch the "value" field here.
10 * It gets zeroed out on fbd structure allocation.
11 * After that we want it to grow continuously
12 * through device resets and power state changes.
14 stat
->u
.old_reg_value_32
= rd32(fbd
, reg
);
17 static void fbnic_hw_stat_rd32(struct fbnic_dev
*fbd
, u32 reg
,
18 struct fbnic_stat_counter
*stat
)
22 new_reg_value
= rd32(fbd
, reg
);
23 stat
->value
+= new_reg_value
- stat
->u
.old_reg_value_32
;
24 stat
->u
.old_reg_value_32
= new_reg_value
;
27 u64
fbnic_stat_rd64(struct fbnic_dev
*fbd
, u32 reg
, u32 offset
)
29 u32 prev_upper
, upper
, lower
, diff
;
31 prev_upper
= rd32(fbd
, reg
+ offset
);
32 lower
= rd32(fbd
, reg
);
33 upper
= rd32(fbd
, reg
+ offset
);
35 diff
= upper
- prev_upper
;
37 return ((u64
)upper
<< 32) | lower
;
40 dev_warn_once(fbd
->dev
,
41 "Stats inconsistent, upper 32b of %#010x updating too quickly\n",
44 /* Return only the upper bits as we cannot guarantee
45 * the accuracy of the lower bits. We will add them in
46 * when the counter slows down enough that we can get
47 * a snapshot with both upper values being the same
50 return ((u64
)upper
<< 32);
53 static void fbnic_hw_stat_rst64(struct fbnic_dev
*fbd
, u32 reg
, s32 offset
,
54 struct fbnic_stat_counter
*stat
)
56 /* Record initial counter values and compute deltas from there to ensure
57 * stats start at 0 after reboot/reset. This avoids exposing absolute
58 * hardware counter values to userspace.
60 stat
->u
.old_reg_value_64
= fbnic_stat_rd64(fbd
, reg
, offset
);
63 static void fbnic_hw_stat_rd64(struct fbnic_dev
*fbd
, u32 reg
, s32 offset
,
64 struct fbnic_stat_counter
*stat
)
68 new_reg_value
= fbnic_stat_rd64(fbd
, reg
, offset
);
69 stat
->value
+= new_reg_value
- stat
->u
.old_reg_value_64
;
70 stat
->u
.old_reg_value_64
= new_reg_value
;
73 static void fbnic_reset_rpc_stats(struct fbnic_dev
*fbd
,
74 struct fbnic_rpc_stats
*rpc
)
76 fbnic_hw_stat_rst32(fbd
,
77 FBNIC_RPC_CNTR_UNKN_ETYPE
,
79 fbnic_hw_stat_rst32(fbd
,
80 FBNIC_RPC_CNTR_UNKN_EXT_HDR
,
82 fbnic_hw_stat_rst32(fbd
, FBNIC_RPC_CNTR_IPV4_FRAG
, &rpc
->ipv4_frag
);
83 fbnic_hw_stat_rst32(fbd
, FBNIC_RPC_CNTR_IPV6_FRAG
, &rpc
->ipv6_frag
);
84 fbnic_hw_stat_rst32(fbd
, FBNIC_RPC_CNTR_IPV4_ESP
, &rpc
->ipv4_esp
);
85 fbnic_hw_stat_rst32(fbd
, FBNIC_RPC_CNTR_IPV6_ESP
, &rpc
->ipv6_esp
);
86 fbnic_hw_stat_rst32(fbd
, FBNIC_RPC_CNTR_TCP_OPT_ERR
, &rpc
->tcp_opt_err
);
87 fbnic_hw_stat_rst32(fbd
,
88 FBNIC_RPC_CNTR_OUT_OF_HDR_ERR
,
89 &rpc
->out_of_hdr_err
);
90 fbnic_hw_stat_rst32(fbd
,
91 FBNIC_RPC_CNTR_OVR_SIZE_ERR
,
95 static void fbnic_get_rpc_stats32(struct fbnic_dev
*fbd
,
96 struct fbnic_rpc_stats
*rpc
)
98 fbnic_hw_stat_rd32(fbd
,
99 FBNIC_RPC_CNTR_UNKN_ETYPE
,
101 fbnic_hw_stat_rd32(fbd
,
102 FBNIC_RPC_CNTR_UNKN_EXT_HDR
,
105 fbnic_hw_stat_rd32(fbd
, FBNIC_RPC_CNTR_IPV4_FRAG
, &rpc
->ipv4_frag
);
106 fbnic_hw_stat_rd32(fbd
, FBNIC_RPC_CNTR_IPV6_FRAG
, &rpc
->ipv6_frag
);
108 fbnic_hw_stat_rd32(fbd
, FBNIC_RPC_CNTR_IPV4_ESP
, &rpc
->ipv4_esp
);
109 fbnic_hw_stat_rd32(fbd
, FBNIC_RPC_CNTR_IPV6_ESP
, &rpc
->ipv6_esp
);
111 fbnic_hw_stat_rd32(fbd
, FBNIC_RPC_CNTR_TCP_OPT_ERR
, &rpc
->tcp_opt_err
);
112 fbnic_hw_stat_rd32(fbd
,
113 FBNIC_RPC_CNTR_OUT_OF_HDR_ERR
,
114 &rpc
->out_of_hdr_err
);
115 fbnic_hw_stat_rd32(fbd
,
116 FBNIC_RPC_CNTR_OVR_SIZE_ERR
,
120 static void fbnic_reset_pcie_stats_asic(struct fbnic_dev
*fbd
,
121 struct fbnic_pcie_stats
*pcie
)
123 fbnic_hw_stat_rst64(fbd
,
124 FBNIC_PUL_USER_OB_RD_TLP_CNT_31_0
,
127 fbnic_hw_stat_rst64(fbd
,
128 FBNIC_PUL_USER_OB_RD_DWORD_CNT_31_0
,
131 fbnic_hw_stat_rst64(fbd
,
132 FBNIC_PUL_USER_OB_CPL_TLP_CNT_31_0
,
135 fbnic_hw_stat_rst64(fbd
,
136 FBNIC_PUL_USER_OB_CPL_DWORD_CNT_31_0
,
138 &pcie
->ob_cpl_dword
);
139 fbnic_hw_stat_rst64(fbd
,
140 FBNIC_PUL_USER_OB_WR_TLP_CNT_31_0
,
143 fbnic_hw_stat_rst64(fbd
,
144 FBNIC_PUL_USER_OB_WR_DWORD_CNT_31_0
,
148 fbnic_hw_stat_rst64(fbd
,
149 FBNIC_PUL_USER_OB_RD_DBG_CNT_TAG_31_0
,
151 &pcie
->ob_rd_no_tag
);
152 fbnic_hw_stat_rst64(fbd
,
153 FBNIC_PUL_USER_OB_RD_DBG_CNT_CPL_CRED_31_0
,
155 &pcie
->ob_rd_no_cpl_cred
);
156 fbnic_hw_stat_rst64(fbd
,
157 FBNIC_PUL_USER_OB_RD_DBG_CNT_NP_CRED_31_0
,
159 &pcie
->ob_rd_no_np_cred
);
162 static void fbnic_get_pcie_stats_asic64(struct fbnic_dev
*fbd
,
163 struct fbnic_pcie_stats
*pcie
)
165 fbnic_hw_stat_rd64(fbd
,
166 FBNIC_PUL_USER_OB_RD_TLP_CNT_31_0
,
169 fbnic_hw_stat_rd64(fbd
,
170 FBNIC_PUL_USER_OB_RD_DWORD_CNT_31_0
,
173 fbnic_hw_stat_rd64(fbd
,
174 FBNIC_PUL_USER_OB_WR_TLP_CNT_31_0
,
177 fbnic_hw_stat_rd64(fbd
,
178 FBNIC_PUL_USER_OB_WR_DWORD_CNT_31_0
,
181 fbnic_hw_stat_rd64(fbd
,
182 FBNIC_PUL_USER_OB_CPL_TLP_CNT_31_0
,
185 fbnic_hw_stat_rd64(fbd
,
186 FBNIC_PUL_USER_OB_CPL_DWORD_CNT_31_0
,
188 &pcie
->ob_cpl_dword
);
190 fbnic_hw_stat_rd64(fbd
,
191 FBNIC_PUL_USER_OB_RD_DBG_CNT_TAG_31_0
,
193 &pcie
->ob_rd_no_tag
);
194 fbnic_hw_stat_rd64(fbd
,
195 FBNIC_PUL_USER_OB_RD_DBG_CNT_CPL_CRED_31_0
,
197 &pcie
->ob_rd_no_cpl_cred
);
198 fbnic_hw_stat_rd64(fbd
,
199 FBNIC_PUL_USER_OB_RD_DBG_CNT_NP_CRED_31_0
,
201 &pcie
->ob_rd_no_np_cred
);
204 void fbnic_reset_hw_stats(struct fbnic_dev
*fbd
)
206 fbnic_reset_rpc_stats(fbd
, &fbd
->hw_stats
.rpc
);
207 fbnic_reset_pcie_stats_asic(fbd
, &fbd
->hw_stats
.pcie
);
210 void fbnic_get_hw_stats32(struct fbnic_dev
*fbd
)
212 fbnic_get_rpc_stats32(fbd
, &fbd
->hw_stats
.rpc
);
215 void fbnic_get_hw_stats(struct fbnic_dev
*fbd
)
217 fbnic_get_hw_stats32(fbd
);
219 fbnic_get_pcie_stats_asic64(fbd
, &fbd
->hw_stats
.pcie
);