xref: /linux/drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c (revision 9fd2da71c301184d98fe37674ca8d017d1ce6600)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright (c) Meta Platforms, Inc. and affiliates. */
3 
4 #include "fbnic.h"
5 
6 static void fbnic_hw_stat_rst32(struct fbnic_dev *fbd, u32 reg,
7 				struct fbnic_stat_counter *stat)
8 {
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.
13 	 */
14 	stat->u.old_reg_value_32 = rd32(fbd, reg);
15 }
16 
17 static void fbnic_hw_stat_rd32(struct fbnic_dev *fbd, u32 reg,
18 			       struct fbnic_stat_counter *stat)
19 {
20 	u32 new_reg_value;
21 
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;
25 }
26 
27 u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset)
28 {
29 	u32 prev_upper, upper, lower, diff;
30 
31 	prev_upper = rd32(fbd, reg + offset);
32 	lower = rd32(fbd, reg);
33 	upper = rd32(fbd, reg + offset);
34 
35 	diff = upper - prev_upper;
36 	if (!diff)
37 		return ((u64)upper << 32) | lower;
38 
39 	if (diff > 1)
40 		dev_warn_once(fbd->dev,
41 			      "Stats inconsistent, upper 32b of %#010x updating too quickly\n",
42 			      reg * 4);
43 
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
48 	 * between reads.
49 	 */
50 	return ((u64)upper << 32);
51 }
52 
53 static void fbnic_hw_stat_rst64(struct fbnic_dev *fbd, u32 reg, s32 offset,
54 				struct fbnic_stat_counter *stat)
55 {
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.
59 	 */
60 	stat->u.old_reg_value_64 = fbnic_stat_rd64(fbd, reg, offset);
61 }
62 
63 static void fbnic_hw_stat_rd64(struct fbnic_dev *fbd, u32 reg, s32 offset,
64 			       struct fbnic_stat_counter *stat)
65 {
66 	u64 new_reg_value;
67 
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;
71 }
72 
73 static void fbnic_reset_tmi_stats(struct fbnic_dev *fbd,
74 				  struct fbnic_tmi_stats *tmi)
75 {
76 	fbnic_hw_stat_rst32(fbd, FBNIC_TMI_DROP_PKTS, &tmi->drop.frames);
77 	fbnic_hw_stat_rst64(fbd, FBNIC_TMI_DROP_BYTE_L, 1, &tmi->drop.bytes);
78 
79 	fbnic_hw_stat_rst32(fbd,
80 			    FBNIC_TMI_ILLEGAL_PTP_REQS,
81 			    &tmi->ptp_illegal_req);
82 	fbnic_hw_stat_rst32(fbd, FBNIC_TMI_GOOD_PTP_TS, &tmi->ptp_good_ts);
83 	fbnic_hw_stat_rst32(fbd, FBNIC_TMI_BAD_PTP_TS, &tmi->ptp_bad_ts);
84 }
85 
86 static void fbnic_get_tmi_stats32(struct fbnic_dev *fbd,
87 				  struct fbnic_tmi_stats *tmi)
88 {
89 	fbnic_hw_stat_rd32(fbd, FBNIC_TMI_DROP_PKTS, &tmi->drop.frames);
90 
91 	fbnic_hw_stat_rd32(fbd,
92 			   FBNIC_TMI_ILLEGAL_PTP_REQS,
93 			   &tmi->ptp_illegal_req);
94 	fbnic_hw_stat_rd32(fbd, FBNIC_TMI_GOOD_PTP_TS, &tmi->ptp_good_ts);
95 	fbnic_hw_stat_rd32(fbd, FBNIC_TMI_BAD_PTP_TS, &tmi->ptp_bad_ts);
96 }
97 
98 static void fbnic_get_tmi_stats(struct fbnic_dev *fbd,
99 				struct fbnic_tmi_stats *tmi)
100 {
101 	fbnic_hw_stat_rd64(fbd, FBNIC_TMI_DROP_BYTE_L, 1, &tmi->drop.bytes);
102 }
103 
104 static void fbnic_reset_tti_stats(struct fbnic_dev *fbd,
105 				  struct fbnic_tti_stats *tti)
106 {
107 	fbnic_hw_stat_rst32(fbd,
108 			    FBNIC_TCE_TTI_CM_DROP_PKTS,
109 			    &tti->cm_drop.frames);
110 	fbnic_hw_stat_rst64(fbd,
111 			    FBNIC_TCE_TTI_CM_DROP_BYTE_L,
112 			    1,
113 			    &tti->cm_drop.bytes);
114 
115 	fbnic_hw_stat_rst32(fbd,
116 			    FBNIC_TCE_TTI_FRAME_DROP_PKTS,
117 			    &tti->frame_drop.frames);
118 	fbnic_hw_stat_rst64(fbd,
119 			    FBNIC_TCE_TTI_FRAME_DROP_BYTE_L,
120 			    1,
121 			    &tti->frame_drop.bytes);
122 
123 	fbnic_hw_stat_rst32(fbd,
124 			    FBNIC_TCE_TBI_DROP_PKTS,
125 			    &tti->tbi_drop.frames);
126 	fbnic_hw_stat_rst64(fbd,
127 			    FBNIC_TCE_TBI_DROP_BYTE_L,
128 			    1,
129 			    &tti->tbi_drop.bytes);
130 }
131 
132 static void fbnic_get_tti_stats32(struct fbnic_dev *fbd,
133 				  struct fbnic_tti_stats *tti)
134 {
135 	fbnic_hw_stat_rd32(fbd,
136 			   FBNIC_TCE_TTI_CM_DROP_PKTS,
137 			   &tti->cm_drop.frames);
138 
139 	fbnic_hw_stat_rd32(fbd,
140 			   FBNIC_TCE_TTI_FRAME_DROP_PKTS,
141 			   &tti->frame_drop.frames);
142 
143 	fbnic_hw_stat_rd32(fbd,
144 			   FBNIC_TCE_TBI_DROP_PKTS,
145 			   &tti->tbi_drop.frames);
146 }
147 
148 static void fbnic_get_tti_stats(struct fbnic_dev *fbd,
149 				struct fbnic_tti_stats *tti)
150 {
151 	fbnic_hw_stat_rd64(fbd,
152 			   FBNIC_TCE_TTI_CM_DROP_BYTE_L,
153 			   1,
154 			   &tti->cm_drop.bytes);
155 
156 	fbnic_hw_stat_rd64(fbd,
157 			   FBNIC_TCE_TTI_FRAME_DROP_BYTE_L,
158 			   1,
159 			   &tti->frame_drop.bytes);
160 
161 	fbnic_hw_stat_rd64(fbd,
162 			   FBNIC_TCE_TBI_DROP_BYTE_L,
163 			   1,
164 			   &tti->tbi_drop.bytes);
165 }
166 
167 static void fbnic_reset_rpc_stats(struct fbnic_dev *fbd,
168 				  struct fbnic_rpc_stats *rpc)
169 {
170 	fbnic_hw_stat_rst32(fbd,
171 			    FBNIC_RPC_CNTR_UNKN_ETYPE,
172 			    &rpc->unkn_etype);
173 	fbnic_hw_stat_rst32(fbd,
174 			    FBNIC_RPC_CNTR_UNKN_EXT_HDR,
175 			    &rpc->unkn_ext_hdr);
176 	fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV4_FRAG, &rpc->ipv4_frag);
177 	fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV6_FRAG, &rpc->ipv6_frag);
178 	fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV4_ESP, &rpc->ipv4_esp);
179 	fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_IPV6_ESP, &rpc->ipv6_esp);
180 	fbnic_hw_stat_rst32(fbd, FBNIC_RPC_CNTR_TCP_OPT_ERR, &rpc->tcp_opt_err);
181 	fbnic_hw_stat_rst32(fbd,
182 			    FBNIC_RPC_CNTR_OUT_OF_HDR_ERR,
183 			    &rpc->out_of_hdr_err);
184 	fbnic_hw_stat_rst32(fbd,
185 			    FBNIC_RPC_CNTR_OVR_SIZE_ERR,
186 			    &rpc->ovr_size_err);
187 }
188 
189 static void fbnic_get_rpc_stats32(struct fbnic_dev *fbd,
190 				  struct fbnic_rpc_stats *rpc)
191 {
192 	fbnic_hw_stat_rd32(fbd,
193 			   FBNIC_RPC_CNTR_UNKN_ETYPE,
194 			   &rpc->unkn_etype);
195 	fbnic_hw_stat_rd32(fbd,
196 			   FBNIC_RPC_CNTR_UNKN_EXT_HDR,
197 			   &rpc->unkn_ext_hdr);
198 
199 	fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV4_FRAG, &rpc->ipv4_frag);
200 	fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV6_FRAG, &rpc->ipv6_frag);
201 
202 	fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV4_ESP, &rpc->ipv4_esp);
203 	fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_IPV6_ESP, &rpc->ipv6_esp);
204 
205 	fbnic_hw_stat_rd32(fbd, FBNIC_RPC_CNTR_TCP_OPT_ERR, &rpc->tcp_opt_err);
206 	fbnic_hw_stat_rd32(fbd,
207 			   FBNIC_RPC_CNTR_OUT_OF_HDR_ERR,
208 			   &rpc->out_of_hdr_err);
209 	fbnic_hw_stat_rd32(fbd,
210 			   FBNIC_RPC_CNTR_OVR_SIZE_ERR,
211 			   &rpc->ovr_size_err);
212 }
213 
214 static void fbnic_reset_rxb_fifo_stats(struct fbnic_dev *fbd, int i,
215 				       struct fbnic_rxb_fifo_stats *fifo)
216 {
217 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_DROP_FRMS_STS(i),
218 			    &fifo->drop.frames);
219 	fbnic_hw_stat_rst64(fbd, FBNIC_RXB_DROP_BYTES_STS_L(i), 1,
220 			    &fifo->drop.bytes);
221 
222 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRUN_FRMS_STS(i),
223 			    &fifo->trunc.frames);
224 	fbnic_hw_stat_rst64(fbd, FBNIC_RXB_TRUN_BYTES_STS_L(i), 1,
225 			    &fifo->trunc.bytes);
226 
227 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRANS_DROP_STS(i),
228 			    &fifo->trans_drop);
229 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRANS_ECN_STS(i),
230 			    &fifo->trans_ecn);
231 
232 	fifo->level.u.old_reg_value_32 = 0;
233 }
234 
235 static void fbnic_reset_rxb_enq_stats(struct fbnic_dev *fbd, int i,
236 				      struct fbnic_rxb_enqueue_stats *enq)
237 {
238 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_DRBO_FRM_CNT_SRC(i),
239 			    &enq->drbo.frames);
240 	fbnic_hw_stat_rst64(fbd, FBNIC_RXB_DRBO_BYTE_CNT_SRC_L(i), 4,
241 			    &enq->drbo.bytes);
242 
243 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_INTEGRITY_ERR(i),
244 			    &enq->integrity_err);
245 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_MAC_ERR(i),
246 			    &enq->mac_err);
247 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_PARSER_ERR(i),
248 			    &enq->parser_err);
249 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_FRM_ERR(i),
250 			    &enq->frm_err);
251 }
252 
253 static void fbnic_reset_rxb_deq_stats(struct fbnic_dev *fbd, int i,
254 				      struct fbnic_rxb_dequeue_stats *deq)
255 {
256 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_INTF_FRM_CNT_DST(i),
257 			    &deq->intf.frames);
258 	fbnic_hw_stat_rst64(fbd, FBNIC_RXB_INTF_BYTE_CNT_DST_L(i), 4,
259 			    &deq->intf.bytes);
260 
261 	fbnic_hw_stat_rst32(fbd, FBNIC_RXB_PBUF_FRM_CNT_DST(i),
262 			    &deq->pbuf.frames);
263 	fbnic_hw_stat_rst64(fbd, FBNIC_RXB_PBUF_BYTE_CNT_DST_L(i), 4,
264 			    &deq->pbuf.bytes);
265 }
266 
267 static void fbnic_reset_rxb_stats(struct fbnic_dev *fbd,
268 				  struct fbnic_rxb_stats *rxb)
269 {
270 	int i;
271 
272 	for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++)
273 		fbnic_reset_rxb_fifo_stats(fbd, i, &rxb->fifo[i]);
274 
275 	for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) {
276 		fbnic_reset_rxb_enq_stats(fbd, i, &rxb->enq[i]);
277 		fbnic_reset_rxb_deq_stats(fbd, i, &rxb->deq[i]);
278 	}
279 }
280 
281 static void fbnic_get_rxb_fifo_stats32(struct fbnic_dev *fbd, int i,
282 				       struct fbnic_rxb_fifo_stats *fifo)
283 {
284 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_DROP_FRMS_STS(i),
285 			   &fifo->drop.frames);
286 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRUN_FRMS_STS(i),
287 			   &fifo->trunc.frames);
288 
289 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRANS_DROP_STS(i),
290 			   &fifo->trans_drop);
291 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRANS_ECN_STS(i),
292 			   &fifo->trans_ecn);
293 
294 	fifo->level.value = rd32(fbd, FBNIC_RXB_PBUF_FIFO_LEVEL(i));
295 }
296 
297 static void fbnic_get_rxb_fifo_stats(struct fbnic_dev *fbd, int i,
298 				     struct fbnic_rxb_fifo_stats *fifo)
299 {
300 	fbnic_hw_stat_rd64(fbd, FBNIC_RXB_DROP_BYTES_STS_L(i), 1,
301 			   &fifo->drop.bytes);
302 	fbnic_hw_stat_rd64(fbd, FBNIC_RXB_TRUN_BYTES_STS_L(i), 1,
303 			   &fifo->trunc.bytes);
304 
305 	fbnic_get_rxb_fifo_stats32(fbd, i, fifo);
306 }
307 
308 static void fbnic_get_rxb_enq_stats32(struct fbnic_dev *fbd, int i,
309 				      struct fbnic_rxb_enqueue_stats *enq)
310 {
311 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_DRBO_FRM_CNT_SRC(i),
312 			   &enq->drbo.frames);
313 
314 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_INTEGRITY_ERR(i),
315 			   &enq->integrity_err);
316 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_MAC_ERR(i),
317 			   &enq->mac_err);
318 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_PARSER_ERR(i),
319 			   &enq->parser_err);
320 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_FRM_ERR(i),
321 			   &enq->frm_err);
322 }
323 
324 static void fbnic_get_rxb_enq_stats(struct fbnic_dev *fbd, int i,
325 				    struct fbnic_rxb_enqueue_stats *enq)
326 {
327 	fbnic_hw_stat_rd64(fbd, FBNIC_RXB_DRBO_BYTE_CNT_SRC_L(i), 4,
328 			   &enq->drbo.bytes);
329 
330 	fbnic_get_rxb_enq_stats32(fbd, i, enq);
331 }
332 
333 static void fbnic_get_rxb_deq_stats32(struct fbnic_dev *fbd, int i,
334 				      struct fbnic_rxb_dequeue_stats *deq)
335 {
336 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_INTF_FRM_CNT_DST(i),
337 			   &deq->intf.frames);
338 	fbnic_hw_stat_rd32(fbd, FBNIC_RXB_PBUF_FRM_CNT_DST(i),
339 			   &deq->pbuf.frames);
340 }
341 
342 static void fbnic_get_rxb_deq_stats(struct fbnic_dev *fbd, int i,
343 				    struct fbnic_rxb_dequeue_stats *deq)
344 {
345 	fbnic_hw_stat_rd64(fbd, FBNIC_RXB_INTF_BYTE_CNT_DST_L(i), 4,
346 			   &deq->intf.bytes);
347 	fbnic_hw_stat_rd64(fbd, FBNIC_RXB_PBUF_BYTE_CNT_DST_L(i), 4,
348 			   &deq->pbuf.bytes);
349 
350 	fbnic_get_rxb_deq_stats32(fbd, i, deq);
351 }
352 
353 static void fbnic_get_rxb_stats32(struct fbnic_dev *fbd,
354 				  struct fbnic_rxb_stats *rxb)
355 {
356 	int i;
357 
358 	for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++)
359 		fbnic_get_rxb_fifo_stats32(fbd, i, &rxb->fifo[i]);
360 
361 	for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) {
362 		fbnic_get_rxb_enq_stats32(fbd, i, &rxb->enq[i]);
363 		fbnic_get_rxb_deq_stats32(fbd, i, &rxb->deq[i]);
364 	}
365 }
366 
367 static void fbnic_get_rxb_stats(struct fbnic_dev *fbd,
368 				struct fbnic_rxb_stats *rxb)
369 {
370 	int i;
371 
372 	for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++)
373 		fbnic_get_rxb_fifo_stats(fbd, i, &rxb->fifo[i]);
374 
375 	for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) {
376 		fbnic_get_rxb_enq_stats(fbd, i, &rxb->enq[i]);
377 		fbnic_get_rxb_deq_stats(fbd, i, &rxb->deq[i]);
378 	}
379 }
380 
381 static void fbnic_reset_hw_rxq_stats(struct fbnic_dev *fbd,
382 				     struct fbnic_hw_q_stats *hw_q)
383 {
384 	int i;
385 
386 	for (i = 0; i < fbd->max_num_queues; i++, hw_q++) {
387 		u32 base = FBNIC_QUEUE(i);
388 
389 		fbnic_hw_stat_rst32(fbd,
390 				    base + FBNIC_QUEUE_RDE_PKT_ERR_CNT,
391 				    &hw_q->rde_pkt_err);
392 		fbnic_hw_stat_rst32(fbd,
393 				    base + FBNIC_QUEUE_RDE_CQ_DROP_CNT,
394 				    &hw_q->rde_pkt_cq_drop);
395 		fbnic_hw_stat_rst32(fbd,
396 				    base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT,
397 				    &hw_q->rde_pkt_bdq_drop);
398 	}
399 }
400 
401 static void fbnic_get_hw_rxq_stats32(struct fbnic_dev *fbd,
402 				     struct fbnic_hw_q_stats *hw_q)
403 {
404 	int i;
405 
406 	for (i = 0; i < fbd->max_num_queues; i++, hw_q++) {
407 		u32 base = FBNIC_QUEUE(i);
408 
409 		fbnic_hw_stat_rd32(fbd,
410 				   base + FBNIC_QUEUE_RDE_PKT_ERR_CNT,
411 				   &hw_q->rde_pkt_err);
412 		fbnic_hw_stat_rd32(fbd,
413 				   base + FBNIC_QUEUE_RDE_CQ_DROP_CNT,
414 				   &hw_q->rde_pkt_cq_drop);
415 		fbnic_hw_stat_rd32(fbd,
416 				   base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT,
417 				   &hw_q->rde_pkt_bdq_drop);
418 	}
419 }
420 
421 void fbnic_get_hw_q_stats(struct fbnic_dev *fbd,
422 			  struct fbnic_hw_q_stats *hw_q)
423 {
424 	spin_lock(&fbd->hw_stats_lock);
425 	fbnic_get_hw_rxq_stats32(fbd, hw_q);
426 	spin_unlock(&fbd->hw_stats_lock);
427 }
428 
429 static void fbnic_reset_pcie_stats_asic(struct fbnic_dev *fbd,
430 					struct fbnic_pcie_stats *pcie)
431 {
432 	fbnic_hw_stat_rst64(fbd,
433 			    FBNIC_PUL_USER_OB_RD_TLP_CNT_31_0,
434 			    1,
435 			    &pcie->ob_rd_tlp);
436 	fbnic_hw_stat_rst64(fbd,
437 			    FBNIC_PUL_USER_OB_RD_DWORD_CNT_31_0,
438 			    1,
439 			    &pcie->ob_rd_dword);
440 	fbnic_hw_stat_rst64(fbd,
441 			    FBNIC_PUL_USER_OB_CPL_TLP_CNT_31_0,
442 			    1,
443 			    &pcie->ob_cpl_tlp);
444 	fbnic_hw_stat_rst64(fbd,
445 			    FBNIC_PUL_USER_OB_CPL_DWORD_CNT_31_0,
446 			    1,
447 			    &pcie->ob_cpl_dword);
448 	fbnic_hw_stat_rst64(fbd,
449 			    FBNIC_PUL_USER_OB_WR_TLP_CNT_31_0,
450 			    1,
451 			    &pcie->ob_wr_tlp);
452 	fbnic_hw_stat_rst64(fbd,
453 			    FBNIC_PUL_USER_OB_WR_DWORD_CNT_31_0,
454 			    1,
455 			    &pcie->ob_wr_dword);
456 
457 	fbnic_hw_stat_rst64(fbd,
458 			    FBNIC_PUL_USER_OB_RD_DBG_CNT_TAG_31_0,
459 			    1,
460 			    &pcie->ob_rd_no_tag);
461 	fbnic_hw_stat_rst64(fbd,
462 			    FBNIC_PUL_USER_OB_RD_DBG_CNT_CPL_CRED_31_0,
463 			    1,
464 			    &pcie->ob_rd_no_cpl_cred);
465 	fbnic_hw_stat_rst64(fbd,
466 			    FBNIC_PUL_USER_OB_RD_DBG_CNT_NP_CRED_31_0,
467 			    1,
468 			    &pcie->ob_rd_no_np_cred);
469 }
470 
471 static void fbnic_get_pcie_stats_asic64(struct fbnic_dev *fbd,
472 					struct fbnic_pcie_stats *pcie)
473 {
474 	fbnic_hw_stat_rd64(fbd,
475 			   FBNIC_PUL_USER_OB_RD_TLP_CNT_31_0,
476 			   1,
477 			   &pcie->ob_rd_tlp);
478 	fbnic_hw_stat_rd64(fbd,
479 			   FBNIC_PUL_USER_OB_RD_DWORD_CNT_31_0,
480 			   1,
481 			   &pcie->ob_rd_dword);
482 	fbnic_hw_stat_rd64(fbd,
483 			   FBNIC_PUL_USER_OB_WR_TLP_CNT_31_0,
484 			   1,
485 			   &pcie->ob_wr_tlp);
486 	fbnic_hw_stat_rd64(fbd,
487 			   FBNIC_PUL_USER_OB_WR_DWORD_CNT_31_0,
488 			   1,
489 			   &pcie->ob_wr_dword);
490 	fbnic_hw_stat_rd64(fbd,
491 			   FBNIC_PUL_USER_OB_CPL_TLP_CNT_31_0,
492 			   1,
493 			   &pcie->ob_cpl_tlp);
494 	fbnic_hw_stat_rd64(fbd,
495 			   FBNIC_PUL_USER_OB_CPL_DWORD_CNT_31_0,
496 			   1,
497 			   &pcie->ob_cpl_dword);
498 
499 	fbnic_hw_stat_rd64(fbd,
500 			   FBNIC_PUL_USER_OB_RD_DBG_CNT_TAG_31_0,
501 			   1,
502 			   &pcie->ob_rd_no_tag);
503 	fbnic_hw_stat_rd64(fbd,
504 			   FBNIC_PUL_USER_OB_RD_DBG_CNT_CPL_CRED_31_0,
505 			   1,
506 			   &pcie->ob_rd_no_cpl_cred);
507 	fbnic_hw_stat_rd64(fbd,
508 			   FBNIC_PUL_USER_OB_RD_DBG_CNT_NP_CRED_31_0,
509 			   1,
510 			   &pcie->ob_rd_no_np_cred);
511 }
512 
513 void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
514 {
515 	spin_lock(&fbd->hw_stats_lock);
516 	fbnic_reset_tmi_stats(fbd, &fbd->hw_stats.tmi);
517 	fbnic_reset_tti_stats(fbd, &fbd->hw_stats.tti);
518 	fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc);
519 	fbnic_reset_rxb_stats(fbd, &fbd->hw_stats.rxb);
520 	fbnic_reset_hw_rxq_stats(fbd, fbd->hw_stats.hw_q);
521 	fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie);
522 	spin_unlock(&fbd->hw_stats_lock);
523 }
524 
525 static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd)
526 {
527 	fbnic_get_tmi_stats32(fbd, &fbd->hw_stats.tmi);
528 	fbnic_get_tti_stats32(fbd, &fbd->hw_stats.tti);
529 	fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc);
530 	fbnic_get_rxb_stats32(fbd, &fbd->hw_stats.rxb);
531 	fbnic_get_hw_rxq_stats32(fbd, fbd->hw_stats.hw_q);
532 }
533 
534 void fbnic_get_hw_stats32(struct fbnic_dev *fbd)
535 {
536 	spin_lock(&fbd->hw_stats_lock);
537 	__fbnic_get_hw_stats32(fbd);
538 	spin_unlock(&fbd->hw_stats_lock);
539 }
540 
541 void fbnic_get_hw_stats(struct fbnic_dev *fbd)
542 {
543 	spin_lock(&fbd->hw_stats_lock);
544 	__fbnic_get_hw_stats32(fbd);
545 
546 	fbnic_get_tmi_stats(fbd, &fbd->hw_stats.tmi);
547 	fbnic_get_tti_stats(fbd, &fbd->hw_stats.tti);
548 	fbnic_get_rxb_stats(fbd, &fbd->hw_stats.rxb);
549 	fbnic_get_pcie_stats_asic64(fbd, &fbd->hw_stats.pcie);
550 	spin_unlock(&fbd->hw_stats_lock);
551 }
552