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

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'eth-fbnic-extend-hardware-stats-coverage'

Mohsin Bashir says:

====================
eth: fbnic: extend hardware stats coverage

This patch series extends the coverage for hardware stats reported via
`ethtool -S`, queue API, and rtnl link stats. The patchset is organized
as follow:

- The first patch adds locking support to protect hardware stats.
- The second patch provides coverage to the hardware queue stats.
- The third patch covers the RX buffer related stats.
- The fourth patch covers the TMI (TX MAC Interface) stats.
- The last patch cover the TTI (TX TEI Interface) stats.
====================

Link: https://patch.msgid.link/20250410070859.4160768-1-mohsin.bashr@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>

+685 -10
+49
Documentation/networking/device_drivers/ethernet/meta/fbnic.rst
··· 31 31 Statistics 32 32 ---------- 33 33 34 + TX MAC Interface 35 + ~~~~~~~~~~~~~~~~ 36 + 37 + - ``ptp_illegal_req``: packets sent to the NIC with PTP request bit set but routed to BMC/FW 38 + - ``ptp_good_ts``: packets successfully routed to MAC with PTP request bit set 39 + - ``ptp_bad_ts``: packets destined for MAC with PTP request bit set but aborted because of some error (e.g., DMA read error) 40 + 41 + TX Extension (TEI) Interface (TTI) 42 + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 43 + 44 + - ``tti_cm_drop``: control messages dropped at the TX Extension (TEI) Interface because of credit starvation 45 + - ``tti_frame_drop``: packets dropped at the TX Extension (TEI) Interface because of credit starvation 46 + - ``tti_tbi_drop``: packets dropped at the TX BMC Interface (TBI) because of credit starvation 47 + 48 + RXB (RX Buffer) Enqueue 49 + ~~~~~~~~~~~~~~~~~~~~~~~ 50 + 51 + - ``rxb_integrity_err[i]``: frames enqueued with integrity errors (e.g., multi-bit ECC errors) on RXB input i 52 + - ``rxb_mac_err[i]``: frames enqueued with MAC end-of-frame errors (e.g., bad FCS) on RXB input i 53 + - ``rxb_parser_err[i]``: frames experienced RPC parser errors 54 + - ``rxb_frm_err[i]``: frames experienced signaling errors (e.g., missing end-of-packet/start-of-packet) on RXB input i 55 + - ``rxb_drbo[i]_frames``: frames received at RXB input i 56 + - ``rxb_drbo[i]_bytes``: bytes received at RXB input i 57 + 58 + RXB (RX Buffer) FIFO 59 + ~~~~~~~~~~~~~~~~~~~~ 60 + 61 + - ``rxb_fifo[i]_drop``: transitions into the drop state on RXB pool i 62 + - ``rxb_fifo[i]_dropped_frames``: frames dropped on RXB pool i 63 + - ``rxb_fifo[i]_ecn``: transitions into the ECN mark state on RXB pool i 64 + - ``rxb_fifo[i]_level``: current occupancy of RXB pool i 65 + 66 + RXB (RX Buffer) Dequeue 67 + ~~~~~~~~~~~~~~~~~~~~~~~ 68 + 69 + - ``rxb_intf[i]_frames``: frames sent to the output i 70 + - ``rxb_intf[i]_bytes``: bytes sent to the output i 71 + - ``rxb_pbuf[i]_frames``: frames sent to output i from the perspective of internal packet buffer 72 + - ``rxb_pbuf[i]_bytes``: bytes sent to output i from the perspective of internal packet buffer 73 + 34 74 RPC (Rx parser) 35 75 ~~~~~~~~~~~~~~~ 36 76 ··· 83 43 - ``rpc_tcp_opt_err``: frames which encountered TCP option parsing error 84 44 - ``rpc_out_of_hdr_err``: frames where header was larger than parsable region 85 45 - ``ovr_size_err``: oversized frames 46 + 47 + Hardware Queues 48 + ~~~~~~~~~~~~~~~ 49 + 50 + 1. RX DMA Engine: 51 + 52 + - ``rde_[i]_pkt_err``: packets with MAC EOP, RPC parser, RXB truncation, or RDE frame truncation errors. These error are flagged in the packet metadata because of cut-through support but the actual drop happens once PCIE/RDE is reached. 53 + - ``rde_[i]_pkt_cq_drop``: packets dropped because RCQ is full 54 + - ``rde_[i]_pkt_bdq_drop``: packets dropped because HPQ or PPQ ran out of host buffer 86 55 87 56 PCIe 88 57 ~~~~
+3
drivers/net/ethernet/meta/fbnic/fbnic.h
··· 81 81 82 82 /* Local copy of hardware statistics */ 83 83 struct fbnic_hw_stats hw_stats; 84 + 85 + /* Lock protecting access to hw_stats */ 86 + spinlock_t hw_stats_lock; 84 87 }; 85 88 86 89 /* Reserve entry 0 in the MSI-X "others" array until we have filled all
+34
drivers/net/ethernet/meta/fbnic/fbnic_csr.h
··· 397 397 #define FBNIC_TCE_DROP_CTRL_TTI_FRM_DROP_EN CSR_BIT(1) 398 398 #define FBNIC_TCE_DROP_CTRL_TTI_TBI_DROP_EN CSR_BIT(2) 399 399 400 + #define FBNIC_TCE_TTI_CM_DROP_PKTS 0x0403e /* 0x100f8 */ 401 + #define FBNIC_TCE_TTI_CM_DROP_BYTE_L 0x0403f /* 0x100fc */ 402 + #define FBNIC_TCE_TTI_CM_DROP_BYTE_H 0x04040 /* 0x10100 */ 403 + #define FBNIC_TCE_TTI_FRAME_DROP_PKTS 0x04041 /* 0x10104 */ 404 + #define FBNIC_TCE_TTI_FRAME_DROP_BYTE_L 0x04042 /* 0x10108 */ 405 + #define FBNIC_TCE_TTI_FRAME_DROP_BYTE_H 0x04043 /* 0x1010c */ 406 + #define FBNIC_TCE_TBI_DROP_PKTS 0x04044 /* 0x10110 */ 407 + #define FBNIC_TCE_TBI_DROP_BYTE_L 0x04045 /* 0x10114 */ 408 + 400 409 #define FBNIC_TCE_TCAM_IDX2DEST_MAP 0x0404A /* 0x10128 */ 401 410 #define FBNIC_TCE_TCAM_IDX2DEST_MAP_DEST_ID_0 CSR_GENMASK(3, 0) 402 411 enum { ··· 441 432 #define FBNIC_TMI_SOP_PROT_CTRL 0x04400 /* 0x11000 */ 442 433 #define FBNIC_TMI_DROP_CTRL 0x04401 /* 0x11004 */ 443 434 #define FBNIC_TMI_DROP_CTRL_EN CSR_BIT(0) 435 + #define FBNIC_TMI_DROP_PKTS 0x04402 /* 0x11008 */ 436 + #define FBNIC_TMI_DROP_BYTE_L 0x04403 /* 0x1100c */ 437 + #define FBNIC_TMI_ILLEGAL_PTP_REQS 0x04409 /* 0x11024 */ 438 + #define FBNIC_TMI_GOOD_PTP_TS 0x0440a /* 0x11028 */ 439 + #define FBNIC_TMI_BAD_PTP_TS 0x0440b /* 0x1102c */ 444 440 #define FBNIC_CSR_END_TMI 0x0443f /* CSR section delimiter */ 445 441 446 442 /* Precision Time Protocol Registers */ ··· 497 483 FBNIC_RXB_FIFO_BMC_TO_HOST = 6, 498 484 /* Unused */ 499 485 FBNIC_RXB_FIFO_INDICES = 8 486 + }; 487 + 488 + enum { 489 + FBNIC_RXB_INTF_NET = 0, 490 + FBNIC_RXB_INTF_RBT = 1, 491 + /* Unused */ 492 + /* Unused */ 493 + FBNIC_RXB_INTF_INDICES = 4 500 494 }; 501 495 502 496 #define FBNIC_RXB_CT_SIZE(n) (0x08000 + (n)) /* 0x20000 + 4*n */ ··· 886 864 #define FBNIC_QUEUE_TWQ1_BAL 0x022 /* 0x088 */ 887 865 #define FBNIC_QUEUE_TWQ1_BAH 0x023 /* 0x08c */ 888 866 867 + /* Tx Work Queue Statistics Registers */ 868 + #define FBNIC_QUEUE_TWQ0_PKT_CNT 0x062 /* 0x188 */ 869 + #define FBNIC_QUEUE_TWQ0_ERR_CNT 0x063 /* 0x18c */ 870 + #define FBNIC_QUEUE_TWQ1_PKT_CNT 0x072 /* 0x1c8 */ 871 + #define FBNIC_QUEUE_TWQ1_ERR_CNT 0x073 /* 0x1cc */ 872 + 889 873 /* Tx Completion Queue Registers */ 890 874 #define FBNIC_QUEUE_TCQ_CTL 0x080 /* 0x200 */ 891 875 #define FBNIC_QUEUE_TCQ_CTL_RESET CSR_BIT(0) ··· 980 952 FBNIC_QUEUE_RDE_CTL1_PAYLD_PACK_ALL = 1, 981 953 FBNIC_QUEUE_RDE_CTL1_PAYLD_PACK_RSS = 2, 982 954 }; 955 + 956 + /* Rx Per CQ Statistics Counters */ 957 + #define FBNIC_QUEUE_RDE_PKT_CNT 0x2a2 /* 0xa88 */ 958 + #define FBNIC_QUEUE_RDE_PKT_ERR_CNT 0x2a3 /* 0xa8c */ 959 + #define FBNIC_QUEUE_RDE_CQ_DROP_CNT 0x2a4 /* 0xa90 */ 960 + #define FBNIC_QUEUE_RDE_BDQ_DROP_CNT 0x2a5 /* 0xa94 */ 983 961 984 962 /* Rx Interrupt Manager Registers */ 985 963 #define FBNIC_QUEUE_RIM_CTL 0x2c0 /* 0xb00 */
+171 -7
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
··· 27 27 FBNIC_STAT_FIELDS(fbnic_hw_stats, name, stat) 28 28 29 29 static const struct fbnic_stat fbnic_gstrings_hw_stats[] = { 30 + /* TTI */ 31 + FBNIC_HW_STAT("tti_cm_drop_frames", tti.cm_drop.frames), 32 + FBNIC_HW_STAT("tti_cm_drop_bytes", tti.cm_drop.bytes), 33 + FBNIC_HW_STAT("tti_frame_drop_frames", tti.frame_drop.frames), 34 + FBNIC_HW_STAT("tti_frame_drop_bytes", tti.frame_drop.bytes), 35 + FBNIC_HW_STAT("tti_tbi_drop_frames", tti.tbi_drop.frames), 36 + FBNIC_HW_STAT("tti_tbi_drop_bytes", tti.tbi_drop.bytes), 37 + 38 + /* TMI */ 39 + FBNIC_HW_STAT("ptp_illegal_req", tmi.ptp_illegal_req), 40 + FBNIC_HW_STAT("ptp_good_ts", tmi.ptp_good_ts), 41 + FBNIC_HW_STAT("ptp_bad_ts", tmi.ptp_bad_ts), 42 + 30 43 /* RPC */ 31 44 FBNIC_HW_STAT("rpc_unkn_etype", rpc.unkn_etype), 32 45 FBNIC_HW_STAT("rpc_unkn_ext_hdr", rpc.unkn_ext_hdr), ··· 52 39 }; 53 40 54 41 #define FBNIC_HW_FIXED_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_stats) 55 - #define FBNIC_HW_STATS_LEN FBNIC_HW_FIXED_STATS_LEN 42 + 43 + #define FBNIC_RXB_ENQUEUE_STAT(name, stat) \ 44 + FBNIC_STAT_FIELDS(fbnic_rxb_enqueue_stats, name, stat) 45 + 46 + static const struct fbnic_stat fbnic_gstrings_rxb_enqueue_stats[] = { 47 + FBNIC_RXB_ENQUEUE_STAT("rxb_integrity_err%u", integrity_err), 48 + FBNIC_RXB_ENQUEUE_STAT("rxb_mac_err%u", mac_err), 49 + FBNIC_RXB_ENQUEUE_STAT("rxb_parser_err%u", parser_err), 50 + FBNIC_RXB_ENQUEUE_STAT("rxb_frm_err%u", frm_err), 51 + 52 + FBNIC_RXB_ENQUEUE_STAT("rxb_drbo%u_frames", drbo.frames), 53 + FBNIC_RXB_ENQUEUE_STAT("rxb_drbo%u_bytes", drbo.bytes), 54 + }; 55 + 56 + #define FBNIC_HW_RXB_ENQUEUE_STATS_LEN \ 57 + ARRAY_SIZE(fbnic_gstrings_rxb_enqueue_stats) 58 + 59 + #define FBNIC_RXB_FIFO_STAT(name, stat) \ 60 + FBNIC_STAT_FIELDS(fbnic_rxb_fifo_stats, name, stat) 61 + 62 + static const struct fbnic_stat fbnic_gstrings_rxb_fifo_stats[] = { 63 + FBNIC_RXB_FIFO_STAT("rxb_fifo%u_drop", trans_drop), 64 + FBNIC_RXB_FIFO_STAT("rxb_fifo%u_dropped_frames", drop.frames), 65 + FBNIC_RXB_FIFO_STAT("rxb_fifo%u_ecn", trans_ecn), 66 + FBNIC_RXB_FIFO_STAT("rxb_fifo%u_level", level), 67 + }; 68 + 69 + #define FBNIC_HW_RXB_FIFO_STATS_LEN ARRAY_SIZE(fbnic_gstrings_rxb_fifo_stats) 70 + 71 + #define FBNIC_RXB_DEQUEUE_STAT(name, stat) \ 72 + FBNIC_STAT_FIELDS(fbnic_rxb_dequeue_stats, name, stat) 73 + 74 + static const struct fbnic_stat fbnic_gstrings_rxb_dequeue_stats[] = { 75 + FBNIC_RXB_DEQUEUE_STAT("rxb_intf%u_frames", intf.frames), 76 + FBNIC_RXB_DEQUEUE_STAT("rxb_intf%u_bytes", intf.bytes), 77 + FBNIC_RXB_DEQUEUE_STAT("rxb_pbuf%u_frames", pbuf.frames), 78 + FBNIC_RXB_DEQUEUE_STAT("rxb_pbuf%u_bytes", pbuf.bytes), 79 + }; 80 + 81 + #define FBNIC_HW_RXB_DEQUEUE_STATS_LEN \ 82 + ARRAY_SIZE(fbnic_gstrings_rxb_dequeue_stats) 83 + 84 + #define FBNIC_HW_Q_STAT(name, stat) \ 85 + FBNIC_STAT_FIELDS(fbnic_hw_q_stats, name, stat.value) 86 + 87 + static const struct fbnic_stat fbnic_gstrings_hw_q_stats[] = { 88 + FBNIC_HW_Q_STAT("rde_%u_pkt_err", rde_pkt_err), 89 + FBNIC_HW_Q_STAT("rde_%u_pkt_cq_drop", rde_pkt_cq_drop), 90 + FBNIC_HW_Q_STAT("rde_%u_pkt_bdq_drop", rde_pkt_bdq_drop), 91 + }; 92 + 93 + #define FBNIC_HW_Q_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_q_stats) 94 + #define FBNIC_HW_STATS_LEN \ 95 + (FBNIC_HW_FIXED_STATS_LEN + \ 96 + FBNIC_HW_RXB_ENQUEUE_STATS_LEN * FBNIC_RXB_ENQUEUE_INDICES + \ 97 + FBNIC_HW_RXB_FIFO_STATS_LEN * FBNIC_RXB_FIFO_INDICES + \ 98 + FBNIC_HW_RXB_DEQUEUE_STATS_LEN * FBNIC_RXB_DEQUEUE_INDICES + \ 99 + FBNIC_HW_Q_STATS_LEN * FBNIC_MAX_QUEUES) 56 100 57 101 static void 58 102 fbnic_get_drvinfo(struct net_device *netdev, struct ethtool_drvinfo *drvinfo) ··· 368 298 return err; 369 299 } 370 300 301 + static void fbnic_get_rxb_enqueue_strings(u8 **data, unsigned int idx) 302 + { 303 + const struct fbnic_stat *stat; 304 + int i; 305 + 306 + stat = fbnic_gstrings_rxb_enqueue_stats; 307 + for (i = 0; i < FBNIC_HW_RXB_ENQUEUE_STATS_LEN; i++, stat++) 308 + ethtool_sprintf(data, stat->string, idx); 309 + } 310 + 311 + static void fbnic_get_rxb_fifo_strings(u8 **data, unsigned int idx) 312 + { 313 + const struct fbnic_stat *stat; 314 + int i; 315 + 316 + stat = fbnic_gstrings_rxb_fifo_stats; 317 + for (i = 0; i < FBNIC_HW_RXB_FIFO_STATS_LEN; i++, stat++) 318 + ethtool_sprintf(data, stat->string, idx); 319 + } 320 + 321 + static void fbnic_get_rxb_dequeue_strings(u8 **data, unsigned int idx) 322 + { 323 + const struct fbnic_stat *stat; 324 + int i; 325 + 326 + stat = fbnic_gstrings_rxb_dequeue_stats; 327 + for (i = 0; i < FBNIC_HW_RXB_DEQUEUE_STATS_LEN; i++, stat++) 328 + ethtool_sprintf(data, stat->string, idx); 329 + } 330 + 371 331 static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data) 372 332 { 373 - int i; 333 + const struct fbnic_stat *stat; 334 + int i, idx; 374 335 375 336 switch (sset) { 376 337 case ETH_SS_STATS: 377 - for (i = 0; i < FBNIC_HW_STATS_LEN; i++) 338 + for (i = 0; i < FBNIC_HW_FIXED_STATS_LEN; i++) 378 339 ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string); 340 + 341 + for (i = 0; i < FBNIC_RXB_ENQUEUE_INDICES; i++) 342 + fbnic_get_rxb_enqueue_strings(&data, i); 343 + 344 + for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++) 345 + fbnic_get_rxb_fifo_strings(&data, i); 346 + 347 + for (i = 0; i < FBNIC_RXB_DEQUEUE_INDICES; i++) 348 + fbnic_get_rxb_dequeue_strings(&data, i); 349 + 350 + for (idx = 0; idx < FBNIC_MAX_QUEUES; idx++) { 351 + stat = fbnic_gstrings_hw_q_stats; 352 + 353 + for (i = 0; i < FBNIC_HW_Q_STATS_LEN; i++, stat++) 354 + ethtool_sprintf(&data, stat->string, idx); 355 + } 379 356 break; 357 + } 358 + } 359 + 360 + static void fbnic_report_hw_stats(const struct fbnic_stat *stat, 361 + const void *base, int len, u64 **data) 362 + { 363 + while (len--) { 364 + u8 *curr = (u8 *)base + stat->offset; 365 + 366 + **data = *(u64 *)curr; 367 + 368 + stat++; 369 + (*data)++; 380 370 } 381 371 } 382 372 ··· 444 314 struct ethtool_stats *stats, u64 *data) 445 315 { 446 316 struct fbnic_net *fbn = netdev_priv(dev); 447 - const struct fbnic_stat *stat; 317 + struct fbnic_dev *fbd = fbn->fbd; 448 318 int i; 449 319 450 320 fbnic_get_hw_stats(fbn->fbd); 451 321 452 - for (i = 0; i < FBNIC_HW_STATS_LEN; i++) { 453 - stat = &fbnic_gstrings_hw_stats[i]; 454 - data[i] = *(u64 *)((u8 *)&fbn->fbd->hw_stats + stat->offset); 322 + spin_lock(&fbd->hw_stats_lock); 323 + fbnic_report_hw_stats(fbnic_gstrings_hw_stats, &fbd->hw_stats, 324 + FBNIC_HW_FIXED_STATS_LEN, &data); 325 + 326 + for (i = 0; i < FBNIC_RXB_ENQUEUE_INDICES; i++) { 327 + const struct fbnic_rxb_enqueue_stats *enq; 328 + 329 + enq = &fbd->hw_stats.rxb.enq[i]; 330 + fbnic_report_hw_stats(fbnic_gstrings_rxb_enqueue_stats, 331 + enq, FBNIC_HW_RXB_ENQUEUE_STATS_LEN, 332 + &data); 455 333 } 334 + 335 + for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++) { 336 + const struct fbnic_rxb_fifo_stats *fifo; 337 + 338 + fifo = &fbd->hw_stats.rxb.fifo[i]; 339 + fbnic_report_hw_stats(fbnic_gstrings_rxb_fifo_stats, 340 + fifo, FBNIC_HW_RXB_FIFO_STATS_LEN, 341 + &data); 342 + } 343 + 344 + for (i = 0; i < FBNIC_RXB_DEQUEUE_INDICES; i++) { 345 + const struct fbnic_rxb_dequeue_stats *deq; 346 + 347 + deq = &fbd->hw_stats.rxb.deq[i]; 348 + fbnic_report_hw_stats(fbnic_gstrings_rxb_dequeue_stats, 349 + deq, FBNIC_HW_RXB_DEQUEUE_STATS_LEN, 350 + &data); 351 + } 352 + 353 + for (i = 0; i < FBNIC_MAX_QUEUES; i++) { 354 + const struct fbnic_hw_q_stats *hw_q = &fbd->hw_stats.hw_q[i]; 355 + 356 + fbnic_report_hw_stats(fbnic_gstrings_hw_q_stats, hw_q, 357 + FBNIC_HW_Q_STATS_LEN, &data); 358 + } 359 + spin_unlock(&fbd->hw_stats_lock); 456 360 } 457 361 458 362 static int fbnic_get_sset_count(struct net_device *dev, int sset)
+333 -2
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
··· 70 70 stat->u.old_reg_value_64 = new_reg_value; 71 71 } 72 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 + 73 167 static void fbnic_reset_rpc_stats(struct fbnic_dev *fbd, 74 168 struct fbnic_rpc_stats *rpc) 75 169 { ··· 209 115 fbnic_hw_stat_rd32(fbd, 210 116 FBNIC_RPC_CNTR_OVR_SIZE_ERR, 211 117 &rpc->ovr_size_err); 118 + } 119 + 120 + static void fbnic_reset_rxb_fifo_stats(struct fbnic_dev *fbd, int i, 121 + struct fbnic_rxb_fifo_stats *fifo) 122 + { 123 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_DROP_FRMS_STS(i), 124 + &fifo->drop.frames); 125 + fbnic_hw_stat_rst64(fbd, FBNIC_RXB_DROP_BYTES_STS_L(i), 1, 126 + &fifo->drop.bytes); 127 + 128 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRUN_FRMS_STS(i), 129 + &fifo->trunc.frames); 130 + fbnic_hw_stat_rst64(fbd, FBNIC_RXB_TRUN_BYTES_STS_L(i), 1, 131 + &fifo->trunc.bytes); 132 + 133 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRANS_DROP_STS(i), 134 + &fifo->trans_drop); 135 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_TRANS_ECN_STS(i), 136 + &fifo->trans_ecn); 137 + 138 + fifo->level.u.old_reg_value_32 = 0; 139 + } 140 + 141 + static void fbnic_reset_rxb_enq_stats(struct fbnic_dev *fbd, int i, 142 + struct fbnic_rxb_enqueue_stats *enq) 143 + { 144 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_DRBO_FRM_CNT_SRC(i), 145 + &enq->drbo.frames); 146 + fbnic_hw_stat_rst64(fbd, FBNIC_RXB_DRBO_BYTE_CNT_SRC_L(i), 4, 147 + &enq->drbo.bytes); 148 + 149 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_INTEGRITY_ERR(i), 150 + &enq->integrity_err); 151 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_MAC_ERR(i), 152 + &enq->mac_err); 153 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_PARSER_ERR(i), 154 + &enq->parser_err); 155 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_FRM_ERR(i), 156 + &enq->frm_err); 157 + } 158 + 159 + static void fbnic_reset_rxb_deq_stats(struct fbnic_dev *fbd, int i, 160 + struct fbnic_rxb_dequeue_stats *deq) 161 + { 162 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_INTF_FRM_CNT_DST(i), 163 + &deq->intf.frames); 164 + fbnic_hw_stat_rst64(fbd, FBNIC_RXB_INTF_BYTE_CNT_DST_L(i), 4, 165 + &deq->intf.bytes); 166 + 167 + fbnic_hw_stat_rst32(fbd, FBNIC_RXB_PBUF_FRM_CNT_DST(i), 168 + &deq->pbuf.frames); 169 + fbnic_hw_stat_rst64(fbd, FBNIC_RXB_PBUF_BYTE_CNT_DST_L(i), 4, 170 + &deq->pbuf.bytes); 171 + } 172 + 173 + static void fbnic_reset_rxb_stats(struct fbnic_dev *fbd, 174 + struct fbnic_rxb_stats *rxb) 175 + { 176 + int i; 177 + 178 + for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++) 179 + fbnic_reset_rxb_fifo_stats(fbd, i, &rxb->fifo[i]); 180 + 181 + for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) { 182 + fbnic_reset_rxb_enq_stats(fbd, i, &rxb->enq[i]); 183 + fbnic_reset_rxb_deq_stats(fbd, i, &rxb->deq[i]); 184 + } 185 + } 186 + 187 + static void fbnic_get_rxb_fifo_stats32(struct fbnic_dev *fbd, int i, 188 + struct fbnic_rxb_fifo_stats *fifo) 189 + { 190 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_DROP_FRMS_STS(i), 191 + &fifo->drop.frames); 192 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRUN_FRMS_STS(i), 193 + &fifo->trunc.frames); 194 + 195 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRANS_DROP_STS(i), 196 + &fifo->trans_drop); 197 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_TRANS_ECN_STS(i), 198 + &fifo->trans_ecn); 199 + 200 + fifo->level.value = rd32(fbd, FBNIC_RXB_PBUF_FIFO_LEVEL(i)); 201 + } 202 + 203 + static void fbnic_get_rxb_fifo_stats(struct fbnic_dev *fbd, int i, 204 + struct fbnic_rxb_fifo_stats *fifo) 205 + { 206 + fbnic_hw_stat_rd64(fbd, FBNIC_RXB_DROP_BYTES_STS_L(i), 1, 207 + &fifo->drop.bytes); 208 + fbnic_hw_stat_rd64(fbd, FBNIC_RXB_TRUN_BYTES_STS_L(i), 1, 209 + &fifo->trunc.bytes); 210 + 211 + fbnic_get_rxb_fifo_stats32(fbd, i, fifo); 212 + } 213 + 214 + static void fbnic_get_rxb_enq_stats32(struct fbnic_dev *fbd, int i, 215 + struct fbnic_rxb_enqueue_stats *enq) 216 + { 217 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_DRBO_FRM_CNT_SRC(i), 218 + &enq->drbo.frames); 219 + 220 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_INTEGRITY_ERR(i), 221 + &enq->integrity_err); 222 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_MAC_ERR(i), 223 + &enq->mac_err); 224 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_PARSER_ERR(i), 225 + &enq->parser_err); 226 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_FRM_ERR(i), 227 + &enq->frm_err); 228 + } 229 + 230 + static void fbnic_get_rxb_enq_stats(struct fbnic_dev *fbd, int i, 231 + struct fbnic_rxb_enqueue_stats *enq) 232 + { 233 + fbnic_hw_stat_rd64(fbd, FBNIC_RXB_DRBO_BYTE_CNT_SRC_L(i), 4, 234 + &enq->drbo.bytes); 235 + 236 + fbnic_get_rxb_enq_stats32(fbd, i, enq); 237 + } 238 + 239 + static void fbnic_get_rxb_deq_stats32(struct fbnic_dev *fbd, int i, 240 + struct fbnic_rxb_dequeue_stats *deq) 241 + { 242 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_INTF_FRM_CNT_DST(i), 243 + &deq->intf.frames); 244 + fbnic_hw_stat_rd32(fbd, FBNIC_RXB_PBUF_FRM_CNT_DST(i), 245 + &deq->pbuf.frames); 246 + } 247 + 248 + static void fbnic_get_rxb_deq_stats(struct fbnic_dev *fbd, int i, 249 + struct fbnic_rxb_dequeue_stats *deq) 250 + { 251 + fbnic_hw_stat_rd64(fbd, FBNIC_RXB_INTF_BYTE_CNT_DST_L(i), 4, 252 + &deq->intf.bytes); 253 + fbnic_hw_stat_rd64(fbd, FBNIC_RXB_PBUF_BYTE_CNT_DST_L(i), 4, 254 + &deq->pbuf.bytes); 255 + 256 + fbnic_get_rxb_deq_stats32(fbd, i, deq); 257 + } 258 + 259 + static void fbnic_get_rxb_stats32(struct fbnic_dev *fbd, 260 + struct fbnic_rxb_stats *rxb) 261 + { 262 + int i; 263 + 264 + for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++) 265 + fbnic_get_rxb_fifo_stats32(fbd, i, &rxb->fifo[i]); 266 + 267 + for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) { 268 + fbnic_get_rxb_enq_stats32(fbd, i, &rxb->enq[i]); 269 + fbnic_get_rxb_deq_stats32(fbd, i, &rxb->deq[i]); 270 + } 271 + } 272 + 273 + static void fbnic_get_rxb_stats(struct fbnic_dev *fbd, 274 + struct fbnic_rxb_stats *rxb) 275 + { 276 + int i; 277 + 278 + for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++) 279 + fbnic_get_rxb_fifo_stats(fbd, i, &rxb->fifo[i]); 280 + 281 + for (i = 0; i < FBNIC_RXB_INTF_INDICES; i++) { 282 + fbnic_get_rxb_enq_stats(fbd, i, &rxb->enq[i]); 283 + fbnic_get_rxb_deq_stats(fbd, i, &rxb->deq[i]); 284 + } 285 + } 286 + 287 + static void fbnic_reset_hw_rxq_stats(struct fbnic_dev *fbd, 288 + struct fbnic_hw_q_stats *hw_q) 289 + { 290 + int i; 291 + 292 + for (i = 0; i < fbd->max_num_queues; i++, hw_q++) { 293 + u32 base = FBNIC_QUEUE(i); 294 + 295 + fbnic_hw_stat_rst32(fbd, 296 + base + FBNIC_QUEUE_RDE_PKT_ERR_CNT, 297 + &hw_q->rde_pkt_err); 298 + fbnic_hw_stat_rst32(fbd, 299 + base + FBNIC_QUEUE_RDE_CQ_DROP_CNT, 300 + &hw_q->rde_pkt_cq_drop); 301 + fbnic_hw_stat_rst32(fbd, 302 + base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT, 303 + &hw_q->rde_pkt_bdq_drop); 304 + } 305 + } 306 + 307 + static void fbnic_get_hw_rxq_stats32(struct fbnic_dev *fbd, 308 + struct fbnic_hw_q_stats *hw_q) 309 + { 310 + int i; 311 + 312 + for (i = 0; i < fbd->max_num_queues; i++, hw_q++) { 313 + u32 base = FBNIC_QUEUE(i); 314 + 315 + fbnic_hw_stat_rd32(fbd, 316 + base + FBNIC_QUEUE_RDE_PKT_ERR_CNT, 317 + &hw_q->rde_pkt_err); 318 + fbnic_hw_stat_rd32(fbd, 319 + base + FBNIC_QUEUE_RDE_CQ_DROP_CNT, 320 + &hw_q->rde_pkt_cq_drop); 321 + fbnic_hw_stat_rd32(fbd, 322 + base + FBNIC_QUEUE_RDE_BDQ_DROP_CNT, 323 + &hw_q->rde_pkt_bdq_drop); 324 + } 325 + } 326 + 327 + void fbnic_get_hw_q_stats(struct fbnic_dev *fbd, 328 + struct fbnic_hw_q_stats *hw_q) 329 + { 330 + spin_lock(&fbd->hw_stats_lock); 331 + fbnic_get_hw_rxq_stats32(fbd, hw_q); 332 + spin_unlock(&fbd->hw_stats_lock); 212 333 } 213 334 214 335 static void fbnic_reset_pcie_stats_asic(struct fbnic_dev *fbd, ··· 512 203 513 204 void fbnic_reset_hw_stats(struct fbnic_dev *fbd) 514 205 { 206 + spin_lock(&fbd->hw_stats_lock); 207 + fbnic_reset_tmi_stats(fbd, &fbd->hw_stats.tmi); 208 + fbnic_reset_tti_stats(fbd, &fbd->hw_stats.tti); 515 209 fbnic_reset_rpc_stats(fbd, &fbd->hw_stats.rpc); 210 + fbnic_reset_rxb_stats(fbd, &fbd->hw_stats.rxb); 211 + fbnic_reset_hw_rxq_stats(fbd, fbd->hw_stats.hw_q); 516 212 fbnic_reset_pcie_stats_asic(fbd, &fbd->hw_stats.pcie); 213 + spin_unlock(&fbd->hw_stats_lock); 214 + } 215 + 216 + static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd) 217 + { 218 + fbnic_get_tmi_stats32(fbd, &fbd->hw_stats.tmi); 219 + fbnic_get_tti_stats32(fbd, &fbd->hw_stats.tti); 220 + fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc); 221 + fbnic_get_rxb_stats32(fbd, &fbd->hw_stats.rxb); 222 + fbnic_get_hw_rxq_stats32(fbd, fbd->hw_stats.hw_q); 517 223 } 518 224 519 225 void fbnic_get_hw_stats32(struct fbnic_dev *fbd) 520 226 { 521 - fbnic_get_rpc_stats32(fbd, &fbd->hw_stats.rpc); 227 + spin_lock(&fbd->hw_stats_lock); 228 + __fbnic_get_hw_stats32(fbd); 229 + spin_unlock(&fbd->hw_stats_lock); 522 230 } 523 231 524 232 void fbnic_get_hw_stats(struct fbnic_dev *fbd) 525 233 { 526 - fbnic_get_hw_stats32(fbd); 234 + spin_lock(&fbd->hw_stats_lock); 235 + __fbnic_get_hw_stats32(fbd); 527 236 237 + fbnic_get_tmi_stats(fbd, &fbd->hw_stats.tmi); 238 + fbnic_get_tti_stats(fbd, &fbd->hw_stats.tti); 239 + fbnic_get_rxb_stats(fbd, &fbd->hw_stats.rxb); 528 240 fbnic_get_pcie_stats_asic64(fbd, &fbd->hw_stats.pcie); 241 + spin_unlock(&fbd->hw_stats_lock); 529 242 }
+48
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
··· 17 17 bool reported; 18 18 }; 19 19 20 + struct fbnic_hw_stat { 21 + struct fbnic_stat_counter frames; 22 + struct fbnic_stat_counter bytes; 23 + }; 24 + 20 25 struct fbnic_eth_mac_stats { 21 26 struct fbnic_stat_counter FramesTransmittedOK; 22 27 struct fbnic_stat_counter FramesReceivedOK; ··· 42 37 struct fbnic_eth_mac_stats eth_mac; 43 38 }; 44 39 40 + struct fbnic_tmi_stats { 41 + struct fbnic_hw_stat drop; 42 + struct fbnic_stat_counter ptp_illegal_req, ptp_good_ts, ptp_bad_ts; 43 + }; 44 + 45 + struct fbnic_tti_stats { 46 + struct fbnic_hw_stat cm_drop, frame_drop, tbi_drop; 47 + }; 48 + 45 49 struct fbnic_rpc_stats { 46 50 struct fbnic_stat_counter unkn_etype, unkn_ext_hdr; 47 51 struct fbnic_stat_counter ipv4_frag, ipv6_frag, ipv4_esp, ipv6_esp; 48 52 struct fbnic_stat_counter tcp_opt_err, out_of_hdr_err, ovr_size_err; 53 + }; 54 + 55 + struct fbnic_rxb_enqueue_stats { 56 + struct fbnic_hw_stat drbo; 57 + struct fbnic_stat_counter integrity_err, mac_err; 58 + struct fbnic_stat_counter parser_err, frm_err; 59 + }; 60 + 61 + struct fbnic_rxb_fifo_stats { 62 + struct fbnic_hw_stat drop, trunc; 63 + struct fbnic_stat_counter trans_drop, trans_ecn; 64 + struct fbnic_stat_counter level; 65 + }; 66 + 67 + struct fbnic_rxb_dequeue_stats { 68 + struct fbnic_hw_stat intf, pbuf; 69 + }; 70 + 71 + struct fbnic_rxb_stats { 72 + struct fbnic_rxb_enqueue_stats enq[FBNIC_RXB_ENQUEUE_INDICES]; 73 + struct fbnic_rxb_fifo_stats fifo[FBNIC_RXB_FIFO_INDICES]; 74 + struct fbnic_rxb_dequeue_stats deq[FBNIC_RXB_DEQUEUE_INDICES]; 75 + }; 76 + 77 + struct fbnic_hw_q_stats { 78 + struct fbnic_stat_counter rde_pkt_err; 79 + struct fbnic_stat_counter rde_pkt_cq_drop; 80 + struct fbnic_stat_counter rde_pkt_bdq_drop; 49 81 }; 50 82 51 83 struct fbnic_pcie_stats { ··· 97 55 98 56 struct fbnic_hw_stats { 99 57 struct fbnic_mac_stats mac; 58 + struct fbnic_tmi_stats tmi; 59 + struct fbnic_tti_stats tti; 100 60 struct fbnic_rpc_stats rpc; 61 + struct fbnic_rxb_stats rxb; 62 + struct fbnic_hw_q_stats hw_q[FBNIC_MAX_QUEUES]; 101 63 struct fbnic_pcie_stats pcie; 102 64 }; 103 65 104 66 u64 fbnic_stat_rd64(struct fbnic_dev *fbd, u32 reg, u32 offset); 105 67 106 68 void fbnic_reset_hw_stats(struct fbnic_dev *fbd); 69 + void fbnic_get_hw_q_stats(struct fbnic_dev *fbd, 70 + struct fbnic_hw_q_stats *hw_q); 107 71 void fbnic_get_hw_stats32(struct fbnic_dev *fbd); 108 72 void fbnic_get_hw_stats(struct fbnic_dev *fbd); 109 73
+46 -1
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c
··· 403 403 static void fbnic_get_stats64(struct net_device *dev, 404 404 struct rtnl_link_stats64 *stats64) 405 405 { 406 + u64 rx_bytes, rx_packets, rx_dropped = 0, rx_errors = 0; 406 407 u64 tx_bytes, tx_packets, tx_dropped = 0; 407 - u64 rx_bytes, rx_packets, rx_dropped = 0; 408 408 struct fbnic_net *fbn = netdev_priv(dev); 409 + struct fbnic_dev *fbd = fbn->fbd; 409 410 struct fbnic_queue_stats *stats; 411 + u64 rx_over = 0, rx_missed = 0; 410 412 unsigned int start, i; 413 + 414 + fbnic_get_hw_stats(fbd); 411 415 412 416 stats = &fbn->tx_stats; 413 417 ··· 422 418 stats64->tx_bytes = tx_bytes; 423 419 stats64->tx_packets = tx_packets; 424 420 stats64->tx_dropped = tx_dropped; 421 + 422 + /* Record drops from Tx HW Datapath */ 423 + tx_dropped += fbd->hw_stats.tmi.drop.frames.value + 424 + fbd->hw_stats.tti.frame_drop.frames.value + 425 + fbd->hw_stats.tti.tbi_drop.frames.value + 426 + fbd->hw_stats.tmi.drop.frames.value; 425 427 426 428 for (i = 0; i < fbn->num_tx_queues; i++) { 427 429 struct fbnic_ring *txr = fbn->tx[i]; ··· 454 444 rx_packets = stats->packets; 455 445 rx_dropped = stats->dropped; 456 446 447 + spin_lock(&fbd->hw_stats_lock); 448 + /* Record drops for the host FIFOs. 449 + * 4: network to Host, 6: BMC to Host 450 + * Exclude the BMC and MC FIFOs as those stats may contain drops 451 + * due to unrelated items such as TCAM misses. They are still 452 + * accessible through the ethtool stats. 453 + */ 454 + i = FBNIC_RXB_FIFO_HOST; 455 + rx_missed += fbd->hw_stats.rxb.fifo[i].drop.frames.value; 456 + i = FBNIC_RXB_FIFO_BMC_TO_HOST; 457 + rx_missed += fbd->hw_stats.rxb.fifo[i].drop.frames.value; 458 + 459 + for (i = 0; i < fbd->max_num_queues; i++) { 460 + /* Report packets dropped due to CQ/BDQ being full/empty */ 461 + rx_over += fbd->hw_stats.hw_q[i].rde_pkt_cq_drop.value; 462 + rx_over += fbd->hw_stats.hw_q[i].rde_pkt_bdq_drop.value; 463 + 464 + /* Report packets with errors */ 465 + rx_errors += fbd->hw_stats.hw_q[i].rde_pkt_err.value; 466 + } 467 + spin_unlock(&fbd->hw_stats_lock); 468 + 457 469 stats64->rx_bytes = rx_bytes; 458 470 stats64->rx_packets = rx_packets; 459 471 stats64->rx_dropped = rx_dropped; 472 + stats64->rx_over_errors = rx_over; 473 + stats64->rx_errors = rx_errors; 474 + stats64->rx_missed_errors = rx_missed; 460 475 461 476 for (i = 0; i < fbn->num_rx_queues; i++) { 462 477 struct fbnic_ring *rxr = fbn->rx[i]; ··· 521 486 { 522 487 struct fbnic_net *fbn = netdev_priv(dev); 523 488 struct fbnic_ring *rxr = fbn->rx[idx]; 489 + struct fbnic_dev *fbd = fbn->fbd; 524 490 struct fbnic_queue_stats *stats; 525 491 u64 bytes, packets, alloc_fail; 526 492 u64 csum_complete, csum_none; ··· 545 509 rx->alloc_fail = alloc_fail; 546 510 rx->csum_complete = csum_complete; 547 511 rx->csum_none = csum_none; 512 + 513 + fbnic_get_hw_q_stats(fbd, fbd->hw_stats.hw_q); 514 + 515 + spin_lock(&fbd->hw_stats_lock); 516 + rx->hw_drop_overruns = fbd->hw_stats.hw_q[idx].rde_pkt_cq_drop.value + 517 + fbd->hw_stats.hw_q[idx].rde_pkt_bdq_drop.value; 518 + rx->hw_drops = fbd->hw_stats.hw_q[idx].rde_pkt_err.value + 519 + rx->hw_drop_overruns; 520 + spin_unlock(&fbd->hw_stats_lock); 548 521 } 549 522 550 523 static void fbnic_get_queue_stats_tx(struct net_device *dev, int idx,
+1
drivers/net/ethernet/meta/fbnic/fbnic_pci.c
··· 292 292 293 293 fbnic_devlink_register(fbd); 294 294 fbnic_dbg_fbd_init(fbd); 295 + spin_lock_init(&fbd->hw_stats_lock); 295 296 296 297 /* Capture snapshot of hardware stats so netdev can calculate delta */ 297 298 fbnic_reset_hw_stats(fbd);