]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
eth: fbnic: add coverage for RXB stats
authorMohsin Bashir <mohsin.bashr@gmail.com>
Thu, 10 Apr 2025 07:08:57 +0000 (00:08 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 15 Apr 2025 09:23:13 +0000 (11:23 +0200)
This patch provides coverage to the RXB (RX Buffer) stats. RXB stats
are divided into 3 sections: RXB enqueue, RXB FIFO, and RXB dequeue
stats.

The RXB enqueue/dequeue stats are indexed from 0-3 and cater for the
input/output counters whereas, the RXB fifo stats are indexed from 0-7.

The RXB also supports pause frame stats counters which we are leaving
for a later patch.

ethtool -S eth0 | grep rxb
     rxb_integrity_err0: 0
     rxb_mac_err0: 0
     rxb_parser_err0: 0
     rxb_frm_err0: 0
     rxb_drbo0_frames: 1433543
     rxb_drbo0_bytes: 775949081
     ---
     ---
     rxb_intf3_frames: 1195711
     rxb_intf3_bytes: 739650210
     rxb_pbuf3_frames: 1195711
     rxb_pbuf3_bytes: 765948092

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-4-mohsin.bashr@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Documentation/networking/device_drivers/ethernet/meta/fbnic.rst
drivers/net/ethernet/meta/fbnic/fbnic_csr.h
drivers/net/ethernet/meta/fbnic/fbnic_ethtool.c
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.c
drivers/net/ethernet/meta/fbnic/fbnic_hw_stats.h
drivers/net/ethernet/meta/fbnic/fbnic_netdev.c

index bc7f2fef287534f6de8fc6df229d702f09b3af57..8ba94ae95db9ccd456a9e1720e6165fc0997b9d7 100644 (file)
@@ -31,6 +31,32 @@ separate entry.
 Statistics
 ----------
 
+RXB (RX Buffer) Enqueue
+~~~~~~~~~~~~~~~~~~~~~~~
+
+ - ``rxb_integrity_err[i]``: frames enqueued with integrity errors (e.g., multi-bit ECC errors) on RXB input i
+ - ``rxb_mac_err[i]``: frames enqueued with MAC end-of-frame errors (e.g., bad FCS) on RXB input i
+ - ``rxb_parser_err[i]``: frames experienced RPC parser errors
+ - ``rxb_frm_err[i]``: frames experienced signaling errors (e.g., missing end-of-packet/start-of-packet) on RXB input i
+ - ``rxb_drbo[i]_frames``: frames received at RXB input i
+ - ``rxb_drbo[i]_bytes``: bytes received at RXB input i
+
+RXB (RX Buffer) FIFO
+~~~~~~~~~~~~~~~~~~~~
+
+ - ``rxb_fifo[i]_drop``: transitions into the drop state on RXB pool i
+ - ``rxb_fifo[i]_dropped_frames``: frames dropped on RXB pool i
+ - ``rxb_fifo[i]_ecn``: transitions into the ECN mark state on RXB pool i
+ - ``rxb_fifo[i]_level``: current occupancy of RXB pool i
+
+RXB (RX Buffer) Dequeue
+~~~~~~~~~~~~~~~~~~~~~~~
+
+   - ``rxb_intf[i]_frames``: frames sent to the output i
+   - ``rxb_intf[i]_bytes``: bytes sent to the output i
+   - ``rxb_pbuf[i]_frames``: frames sent to output i from the perspective of internal packet buffer
+   - ``rxb_pbuf[i]_bytes``: bytes sent to output i from the perspective of internal packet buffer
+
 RPC (Rx parser)
 ~~~~~~~~~~~~~~~
 
index ff5f68c7e73d557e66c67d0ad185d376b4c97849..a554e0b2cfffda4b2ff38a05788988407b0143af 100644 (file)
@@ -485,6 +485,14 @@ enum {
        FBNIC_RXB_FIFO_INDICES          = 8
 };
 
+enum {
+       FBNIC_RXB_INTF_NET = 0,
+       FBNIC_RXB_INTF_RBT = 1,
+       /* Unused */
+       /* Unused */
+       FBNIC_RXB_INTF_INDICES  = 4
+};
+
 #define FBNIC_RXB_CT_SIZE(n)           (0x08000 + (n)) /* 0x20000 + 4*n */
 #define FBNIC_RXB_CT_SIZE_CNT                  8
 #define FBNIC_RXB_CT_SIZE_HEADER               CSR_GENMASK(5, 0)
index 038e969f5ba38c2667c62d16413785ad2c87898c..816af96a5d5fc6b1162108f8289c0409b9bc65ba 100644 (file)
@@ -40,6 +40,47 @@ static const struct fbnic_stat fbnic_gstrings_hw_stats[] = {
 
 #define FBNIC_HW_FIXED_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_stats)
 
+#define FBNIC_RXB_ENQUEUE_STAT(name, stat) \
+       FBNIC_STAT_FIELDS(fbnic_rxb_enqueue_stats, name, stat)
+
+static const struct fbnic_stat fbnic_gstrings_rxb_enqueue_stats[] = {
+       FBNIC_RXB_ENQUEUE_STAT("rxb_integrity_err%u", integrity_err),
+       FBNIC_RXB_ENQUEUE_STAT("rxb_mac_err%u", mac_err),
+       FBNIC_RXB_ENQUEUE_STAT("rxb_parser_err%u", parser_err),
+       FBNIC_RXB_ENQUEUE_STAT("rxb_frm_err%u", frm_err),
+
+       FBNIC_RXB_ENQUEUE_STAT("rxb_drbo%u_frames", drbo.frames),
+       FBNIC_RXB_ENQUEUE_STAT("rxb_drbo%u_bytes", drbo.bytes),
+};
+
+#define FBNIC_HW_RXB_ENQUEUE_STATS_LEN \
+       ARRAY_SIZE(fbnic_gstrings_rxb_enqueue_stats)
+
+#define FBNIC_RXB_FIFO_STAT(name, stat) \
+       FBNIC_STAT_FIELDS(fbnic_rxb_fifo_stats, name, stat)
+
+static const struct fbnic_stat fbnic_gstrings_rxb_fifo_stats[] = {
+       FBNIC_RXB_FIFO_STAT("rxb_fifo%u_drop", trans_drop),
+       FBNIC_RXB_FIFO_STAT("rxb_fifo%u_dropped_frames", drop.frames),
+       FBNIC_RXB_FIFO_STAT("rxb_fifo%u_ecn", trans_ecn),
+       FBNIC_RXB_FIFO_STAT("rxb_fifo%u_level", level),
+};
+
+#define FBNIC_HW_RXB_FIFO_STATS_LEN ARRAY_SIZE(fbnic_gstrings_rxb_fifo_stats)
+
+#define FBNIC_RXB_DEQUEUE_STAT(name, stat) \
+       FBNIC_STAT_FIELDS(fbnic_rxb_dequeue_stats, name, stat)
+
+static const struct fbnic_stat fbnic_gstrings_rxb_dequeue_stats[] = {
+       FBNIC_RXB_DEQUEUE_STAT("rxb_intf%u_frames", intf.frames),
+       FBNIC_RXB_DEQUEUE_STAT("rxb_intf%u_bytes", intf.bytes),
+       FBNIC_RXB_DEQUEUE_STAT("rxb_pbuf%u_frames", pbuf.frames),
+       FBNIC_RXB_DEQUEUE_STAT("rxb_pbuf%u_bytes", pbuf.bytes),
+};
+
+#define FBNIC_HW_RXB_DEQUEUE_STATS_LEN \
+       ARRAY_SIZE(fbnic_gstrings_rxb_dequeue_stats)
+
 #define FBNIC_HW_Q_STAT(name, stat) \
        FBNIC_STAT_FIELDS(fbnic_hw_q_stats, name, stat.value)
 
@@ -52,6 +93,9 @@ static const struct fbnic_stat fbnic_gstrings_hw_q_stats[] = {
 #define FBNIC_HW_Q_STATS_LEN ARRAY_SIZE(fbnic_gstrings_hw_q_stats)
 #define FBNIC_HW_STATS_LEN \
        (FBNIC_HW_FIXED_STATS_LEN + \
+        FBNIC_HW_RXB_ENQUEUE_STATS_LEN * FBNIC_RXB_ENQUEUE_INDICES + \
+        FBNIC_HW_RXB_FIFO_STATS_LEN * FBNIC_RXB_FIFO_INDICES + \
+        FBNIC_HW_RXB_DEQUEUE_STATS_LEN * FBNIC_RXB_DEQUEUE_INDICES + \
         FBNIC_HW_Q_STATS_LEN * FBNIC_MAX_QUEUES)
 
 static void
@@ -311,6 +355,36 @@ err_free_clone:
        return err;
 }
 
+static void fbnic_get_rxb_enqueue_strings(u8 **data, unsigned int idx)
+{
+       const struct fbnic_stat *stat;
+       int i;
+
+       stat = fbnic_gstrings_rxb_enqueue_stats;
+       for (i = 0; i < FBNIC_HW_RXB_ENQUEUE_STATS_LEN; i++, stat++)
+               ethtool_sprintf(data, stat->string, idx);
+}
+
+static void fbnic_get_rxb_fifo_strings(u8 **data, unsigned int idx)
+{
+       const struct fbnic_stat *stat;
+       int i;
+
+       stat = fbnic_gstrings_rxb_fifo_stats;
+       for (i = 0; i < FBNIC_HW_RXB_FIFO_STATS_LEN; i++, stat++)
+               ethtool_sprintf(data, stat->string, idx);
+}
+
+static void fbnic_get_rxb_dequeue_strings(u8 **data, unsigned int idx)
+{
+       const struct fbnic_stat *stat;
+       int i;
+
+       stat = fbnic_gstrings_rxb_dequeue_stats;
+       for (i = 0; i < FBNIC_HW_RXB_DEQUEUE_STATS_LEN; i++, stat++)
+               ethtool_sprintf(data, stat->string, idx);
+}
+
 static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
 {
        const struct fbnic_stat *stat;
@@ -321,6 +395,15 @@ static void fbnic_get_strings(struct net_device *dev, u32 sset, u8 *data)
                for (i = 0; i < FBNIC_HW_FIXED_STATS_LEN; i++)
                        ethtool_puts(&data, fbnic_gstrings_hw_stats[i].string);
 
+               for (i = 0; i < FBNIC_RXB_ENQUEUE_INDICES; i++)
+                       fbnic_get_rxb_enqueue_strings(&data, i);
+
+               for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++)
+                       fbnic_get_rxb_fifo_strings(&data, i);
+
+               for (i = 0; i < FBNIC_RXB_DEQUEUE_INDICES; i++)
+                       fbnic_get_rxb_dequeue_strings(&data, i);
+
                for (idx = 0; idx < FBNIC_MAX_QUEUES; idx++) {
                        stat = fbnic_gstrings_hw_q_stats;
 
@@ -357,6 +440,33 @@ static void fbnic_get_ethtool_stats(struct net_device *dev,
        fbnic_report_hw_stats(fbnic_gstrings_hw_stats, &fbd->hw_stats,
                              FBNIC_HW_FIXED_STATS_LEN, &data);
 
+       for (i = 0; i < FBNIC_RXB_ENQUEUE_INDICES; i++) {
+               const struct fbnic_rxb_enqueue_stats *enq;
+
+               enq = &fbd->hw_stats.rxb.enq[i];
+               fbnic_report_hw_stats(fbnic_gstrings_rxb_enqueue_stats,
+                                     enq, FBNIC_HW_RXB_ENQUEUE_STATS_LEN,
+                                     &data);
+       }
+
+       for (i = 0; i < FBNIC_RXB_FIFO_INDICES; i++) {
+               const struct fbnic_rxb_fifo_stats *fifo;
+
+               fifo = &fbd->hw_stats.rxb.fifo[i];
+               fbnic_report_hw_stats(fbnic_gstrings_rxb_fifo_stats,
+                                     fifo, FBNIC_HW_RXB_FIFO_STATS_LEN,
+                                     &data);
+       }
+
+       for (i = 0; i < FBNIC_RXB_DEQUEUE_INDICES; i++) {
+               const struct fbnic_rxb_dequeue_stats *deq;
+
+               deq = &fbd->hw_stats.rxb.deq[i];
+               fbnic_report_hw_stats(fbnic_gstrings_rxb_dequeue_stats,
+                                     deq, FBNIC_HW_RXB_DEQUEUE_STATS_LEN,
+                                     &data);
+       }
+
        for (i  = 0; i < FBNIC_MAX_QUEUES; i++) {
                const struct fbnic_hw_q_stats *hw_q = &fbd->hw_stats.hw_q[i];
 
index c8faedc2ec44330c913fa5da11753598a714416a..1c5ccaf397277aaa0cf9324e4a40111713e48007 100644 (file)
@@ -117,6 +117,173 @@ static void fbnic_get_rpc_stats32(struct fbnic_dev *fbd,
                           &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)
 {
@@ -253,6 +420,7 @@ void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
 {
        spin_lock(&fbd->hw_stats_lock);
        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);
@@ -261,6 +429,7 @@ void fbnic_reset_hw_stats(struct fbnic_dev *fbd)
 static void __fbnic_get_hw_stats32(struct fbnic_dev *fbd)
 {
        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);
 }
 
@@ -275,6 +444,8 @@ void fbnic_get_hw_stats(struct fbnic_dev *fbd)
 {
        spin_lock(&fbd->hw_stats_lock);
        __fbnic_get_hw_stats32(fbd);
+
+       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);
 }
index 81efa8dc83812ccbd4707f2ad953eab34dccc93f..ec03e6253ba5a8c3d9eaf0e1e8802694a5ea3606 100644 (file)
@@ -17,6 +17,11 @@ struct fbnic_stat_counter {
        bool reported;
 };
 
+struct fbnic_hw_stat {
+       struct fbnic_stat_counter frames;
+       struct fbnic_stat_counter bytes;
+};
+
 struct fbnic_eth_mac_stats {
        struct fbnic_stat_counter FramesTransmittedOK;
        struct fbnic_stat_counter FramesReceivedOK;
@@ -43,6 +48,28 @@ struct fbnic_rpc_stats {
        struct fbnic_stat_counter tcp_opt_err, out_of_hdr_err, ovr_size_err;
 };
 
+struct fbnic_rxb_enqueue_stats {
+       struct fbnic_hw_stat drbo;
+       struct fbnic_stat_counter integrity_err, mac_err;
+       struct fbnic_stat_counter parser_err, frm_err;
+};
+
+struct fbnic_rxb_fifo_stats {
+       struct fbnic_hw_stat drop, trunc;
+       struct fbnic_stat_counter trans_drop, trans_ecn;
+       struct fbnic_stat_counter level;
+};
+
+struct fbnic_rxb_dequeue_stats {
+       struct fbnic_hw_stat intf, pbuf;
+};
+
+struct fbnic_rxb_stats {
+       struct fbnic_rxb_enqueue_stats enq[FBNIC_RXB_ENQUEUE_INDICES];
+       struct fbnic_rxb_fifo_stats fifo[FBNIC_RXB_FIFO_INDICES];
+       struct fbnic_rxb_dequeue_stats deq[FBNIC_RXB_DEQUEUE_INDICES];
+};
+
 struct fbnic_hw_q_stats {
        struct fbnic_stat_counter rde_pkt_err;
        struct fbnic_stat_counter rde_pkt_cq_drop;
@@ -62,6 +89,7 @@ struct fbnic_pcie_stats {
 struct fbnic_hw_stats {
        struct fbnic_mac_stats mac;
        struct fbnic_rpc_stats rpc;
+       struct fbnic_rxb_stats rxb;
        struct fbnic_hw_q_stats hw_q[FBNIC_MAX_QUEUES];
        struct fbnic_pcie_stats pcie;
 };
index e19284d4b91d60bde90ec5870719b2a2463da1ee..dff485511301420219557acf445b85de6d3f409d 100644 (file)
@@ -408,8 +408,8 @@ static void fbnic_get_stats64(struct net_device *dev,
        struct fbnic_net *fbn = netdev_priv(dev);
        struct fbnic_dev *fbd = fbn->fbd;
        struct fbnic_queue_stats *stats;
+       u64 rx_over = 0, rx_missed = 0;
        unsigned int start, i;
-       u64 rx_over = 0;
 
        fbnic_get_hw_stats(fbd);
 
@@ -449,6 +449,17 @@ static void fbnic_get_stats64(struct net_device *dev,
        rx_dropped = stats->dropped;
 
        spin_lock(&fbd->hw_stats_lock);
+       /* Record drops for the host FIFOs.
+        * 4: network to Host,  6: BMC to Host
+        * Exclude the BMC and MC FIFOs as those stats may contain drops
+        * due to unrelated items such as TCAM misses. They are still
+        * accessible through the ethtool stats.
+        */
+       i = FBNIC_RXB_FIFO_HOST;
+       rx_missed += fbd->hw_stats.rxb.fifo[i].drop.frames.value;
+       i = FBNIC_RXB_FIFO_BMC_TO_HOST;
+       rx_missed += fbd->hw_stats.rxb.fifo[i].drop.frames.value;
+
        for (i = 0; i < fbd->max_num_queues; i++) {
                /* Report packets dropped due to CQ/BDQ being full/empty */
                rx_over += fbd->hw_stats.hw_q[i].rde_pkt_cq_drop.value;
@@ -464,6 +475,7 @@ static void fbnic_get_stats64(struct net_device *dev,
        stats64->rx_dropped = rx_dropped;
        stats64->rx_over_errors = rx_over;
        stats64->rx_errors = rx_errors;
+       stats64->rx_missed_errors = rx_missed;
 
        for (i = 0; i < fbn->num_rx_queues; i++) {
                struct fbnic_ring *rxr = fbn->rx[i];