RDMA/bnxt_re: expose detailed stats retrieved from HW
authorSelvin Xavier <selvin.xavier@broadcom.com>
Thu, 11 Jan 2018 16:52:10 +0000 (11:52 -0500)
committerDoug Ledford <dledford@redhat.com>
Thu, 18 Jan 2018 19:49:18 +0000 (14:49 -0500)
Broadcom's adapter supports more granular statistics
to allow better understanding about the state of the
chip when data traffic is flowing.

Exposing the detailed stats to the consumer through
the standard hook available in the kverbs interface.
In order to retrieve all the information, driver
implements a firmware command.

Signed-off-by: Selvin Xavier <selvin.xavier@broadcom.com>
Signed-off-by: Devesh Sharma <devesh.sharma@broadcom.com>
Signed-off-by: Doug Ledford <dledford@redhat.com>
drivers/infiniband/hw/bnxt_re/bnxt_re.h
drivers/infiniband/hw/bnxt_re/hw_counters.c
drivers/infiniband/hw/bnxt_re/hw_counters.h
drivers/infiniband/hw/bnxt_re/main.c
drivers/infiniband/hw/bnxt_re/qplib_sp.c
drivers/infiniband/hw/bnxt_re/qplib_sp.h
drivers/infiniband/hw/bnxt_re/roce_hsi.h

index 085ca000973e7d9525ca2cf947fdc8f640e7c4b3..ca32057e886f00af4287cbe586c81866a3367ae4 100644 (file)
@@ -121,6 +121,7 @@ struct bnxt_re_dev {
 #define BNXT_RE_FLAG_RCFW_CHANNEL_EN           4
 #define BNXT_RE_FLAG_QOS_WORK_REG              5
 #define BNXT_RE_FLAG_TASK_IN_PROG              6
+#define BNXT_RE_FLAG_ISSUE_ROCE_STATS          29
        struct net_device               *netdev;
        unsigned int                    version, major, minor;
        struct bnxt_en_dev              *en_dev;
@@ -168,6 +169,7 @@ struct bnxt_re_dev {
        atomic_t nq_alloc_cnt;
        u32 is_virtfn;
        u32 num_vfs;
+       struct bnxt_qplib_roce_stats    stats;
 };
 
 #define to_bnxt_re_dev(ptr, member)    \
index 7b28219eba46ea6d16296419cc0ca6289eec878c..77416bc61e6e8b134f07b745cc372606eb5dd148 100644 (file)
 #include "hw_counters.h"
 
 static const char * const bnxt_re_stat_name[] = {
-       [BNXT_RE_ACTIVE_QP]           =  "active_qps",
-       [BNXT_RE_ACTIVE_SRQ]          =  "active_srqs",
-       [BNXT_RE_ACTIVE_CQ]           =  "active_cqs",
-       [BNXT_RE_ACTIVE_MR]           =  "active_mrs",
-       [BNXT_RE_ACTIVE_MW]           =  "active_mws",
-       [BNXT_RE_RX_PKTS]             =  "rx_pkts",
-       [BNXT_RE_RX_BYTES]            =  "rx_bytes",
-       [BNXT_RE_TX_PKTS]             =  "tx_pkts",
-       [BNXT_RE_TX_BYTES]            =  "tx_bytes",
-       [BNXT_RE_RECOVERABLE_ERRORS]  =  "recoverable_errors"
+       [BNXT_RE_ACTIVE_QP]             =  "active_qps",
+       [BNXT_RE_ACTIVE_SRQ]            =  "active_srqs",
+       [BNXT_RE_ACTIVE_CQ]             =  "active_cqs",
+       [BNXT_RE_ACTIVE_MR]             =  "active_mrs",
+       [BNXT_RE_ACTIVE_MW]             =  "active_mws",
+       [BNXT_RE_RX_PKTS]               =  "rx_pkts",
+       [BNXT_RE_RX_BYTES]              =  "rx_bytes",
+       [BNXT_RE_TX_PKTS]               =  "tx_pkts",
+       [BNXT_RE_TX_BYTES]              =  "tx_bytes",
+       [BNXT_RE_RECOVERABLE_ERRORS]    =  "recoverable_errors",
+       [BNXT_RE_TO_RETRANSMITS]        = "to_retransmits",
+       [BNXT_RE_SEQ_ERR_NAKS_RCVD]     = "seq_err_naks_rcvd",
+       [BNXT_RE_MAX_RETRY_EXCEEDED]    = "max_retry_exceeded",
+       [BNXT_RE_RNR_NAKS_RCVD]         = "rnr_naks_rcvd",
+       [BNXT_RE_MISSING_RESP]          = "missin_resp",
+       [BNXT_RE_UNRECOVERABLE_ERR]     = "unrecoverable_err",
+       [BNXT_RE_BAD_RESP_ERR]          = "bad_resp_err",
+       [BNXT_RE_LOCAL_QP_OP_ERR]       = "local_qp_op_err",
+       [BNXT_RE_LOCAL_PROTECTION_ERR]  = "local_protection_err",
+       [BNXT_RE_MEM_MGMT_OP_ERR]       = "mem_mgmt_op_err",
+       [BNXT_RE_REMOTE_INVALID_REQ_ERR] = "remote_invalid_req_err",
+       [BNXT_RE_REMOTE_ACCESS_ERR]     = "remote_access_err",
+       [BNXT_RE_REMOTE_OP_ERR]         = "remote_op_err",
+       [BNXT_RE_DUP_REQ]               = "dup_req",
+       [BNXT_RE_RES_EXCEED_MAX]        = "res_exceed_max",
+       [BNXT_RE_RES_LENGTH_MISMATCH]   = "res_length_mismatch",
+       [BNXT_RE_RES_EXCEEDS_WQE]       = "res_exceeds_wqe",
+       [BNXT_RE_RES_OPCODE_ERR]        = "res_opcode_err",
+       [BNXT_RE_RES_RX_INVALID_RKEY]   = "res_rx_invalid_rkey",
+       [BNXT_RE_RES_RX_DOMAIN_ERR]     = "res_rx_domain_err",
+       [BNXT_RE_RES_RX_NO_PERM]        = "res_rx_no_perm",
+       [BNXT_RE_RES_RX_RANGE_ERR]      = "res_rx_range_err",
+       [BNXT_RE_RES_TX_INVALID_RKEY]   = "res_tx_invalid_rkey",
+       [BNXT_RE_RES_TX_DOMAIN_ERR]     = "res_tx_domain_err",
+       [BNXT_RE_RES_TX_NO_PERM]        = "res_tx_no_perm",
+       [BNXT_RE_RES_TX_RANGE_ERR]      = "res_tx_range_err",
+       [BNXT_RE_RES_IRRQ_OFLOW]        = "res_irrq_oflow",
+       [BNXT_RE_RES_UNSUP_OPCODE]      = "res_unsup_opcode",
+       [BNXT_RE_RES_UNALIGNED_ATOMIC]  = "res_unaligned_atomic",
+       [BNXT_RE_RES_REM_INV_ERR]       = "res_rem_inv_err",
+       [BNXT_RE_RES_MEM_ERROR]         = "res_mem_err",
+       [BNXT_RE_RES_SRQ_ERR]           = "res_srq_err",
+       [BNXT_RE_RES_CMP_ERR]           = "res_cmp_err",
+       [BNXT_RE_RES_INVALID_DUP_RKEY]  = "res_invalid_dup_rkey",
+       [BNXT_RE_RES_WQE_FORMAT_ERR]    = "res_wqe_format_err",
+       [BNXT_RE_RES_CQ_LOAD_ERR]       = "res_cq_load_err",
+       [BNXT_RE_RES_SRQ_LOAD_ERR]      = "res_srq_load_err",
+       [BNXT_RE_RES_TX_PCI_ERR]        = "res_tx_pci_err",
+       [BNXT_RE_RES_RX_PCI_ERR]        = "res_rx_pci_err"
 };
 
 int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
@@ -76,6 +115,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
 {
        struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
        struct ctx_hw_stats *bnxt_re_stats = rdev->qplib_ctx.stats.dma;
+       int rc  = 0;
 
        if (!port || !stats)
                return -EINVAL;
@@ -97,6 +137,91 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
                stats->value[BNXT_RE_TX_BYTES] =
                        le64_to_cpu(bnxt_re_stats->tx_ucast_bytes);
        }
+       if (test_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags)) {
+               rc = bnxt_qplib_get_roce_stats(&rdev->rcfw, &rdev->stats);
+               if (rc)
+                       clear_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS,
+                                 &rdev->flags);
+               stats->value[BNXT_RE_TO_RETRANSMITS] =
+                                       rdev->stats.to_retransmits;
+               stats->value[BNXT_RE_SEQ_ERR_NAKS_RCVD] =
+                                       rdev->stats.seq_err_naks_rcvd;
+               stats->value[BNXT_RE_MAX_RETRY_EXCEEDED] =
+                                       rdev->stats.max_retry_exceeded;
+               stats->value[BNXT_RE_RNR_NAKS_RCVD] =
+                                       rdev->stats.rnr_naks_rcvd;
+               stats->value[BNXT_RE_MISSING_RESP] =
+                                       rdev->stats.missing_resp;
+               stats->value[BNXT_RE_UNRECOVERABLE_ERR] =
+                                       rdev->stats.unrecoverable_err;
+               stats->value[BNXT_RE_BAD_RESP_ERR] =
+                                       rdev->stats.bad_resp_err;
+               stats->value[BNXT_RE_LOCAL_QP_OP_ERR]   =
+                               rdev->stats.local_qp_op_err;
+               stats->value[BNXT_RE_LOCAL_PROTECTION_ERR] =
+                               rdev->stats.local_protection_err;
+               stats->value[BNXT_RE_MEM_MGMT_OP_ERR] =
+                               rdev->stats.mem_mgmt_op_err;
+               stats->value[BNXT_RE_REMOTE_INVALID_REQ_ERR] =
+                               rdev->stats.remote_invalid_req_err;
+               stats->value[BNXT_RE_REMOTE_ACCESS_ERR] =
+                               rdev->stats.remote_access_err;
+               stats->value[BNXT_RE_REMOTE_OP_ERR] =
+                               rdev->stats.remote_op_err;
+               stats->value[BNXT_RE_DUP_REQ] =
+                               rdev->stats.dup_req;
+               stats->value[BNXT_RE_RES_EXCEED_MAX] =
+                               rdev->stats.res_exceed_max;
+               stats->value[BNXT_RE_RES_LENGTH_MISMATCH] =
+                               rdev->stats.res_length_mismatch;
+               stats->value[BNXT_RE_RES_EXCEEDS_WQE] =
+                               rdev->stats.res_exceeds_wqe;
+               stats->value[BNXT_RE_RES_OPCODE_ERR] =
+                               rdev->stats.res_opcode_err;
+               stats->value[BNXT_RE_RES_RX_INVALID_RKEY] =
+                               rdev->stats.res_rx_invalid_rkey;
+               stats->value[BNXT_RE_RES_RX_DOMAIN_ERR] =
+                               rdev->stats.res_rx_domain_err;
+               stats->value[BNXT_RE_RES_RX_NO_PERM] =
+                               rdev->stats.res_rx_no_perm;
+               stats->value[BNXT_RE_RES_RX_RANGE_ERR]  =
+                               rdev->stats.res_rx_range_err;
+               stats->value[BNXT_RE_RES_TX_INVALID_RKEY] =
+                               rdev->stats.res_tx_invalid_rkey;
+               stats->value[BNXT_RE_RES_TX_DOMAIN_ERR] =
+                               rdev->stats.res_tx_domain_err;
+               stats->value[BNXT_RE_RES_TX_NO_PERM] =
+                               rdev->stats.res_tx_no_perm;
+               stats->value[BNXT_RE_RES_TX_RANGE_ERR]  =
+                               rdev->stats.res_tx_range_err;
+               stats->value[BNXT_RE_RES_IRRQ_OFLOW] =
+                               rdev->stats.res_irrq_oflow;
+               stats->value[BNXT_RE_RES_UNSUP_OPCODE]  =
+                               rdev->stats.res_unsup_opcode;
+               stats->value[BNXT_RE_RES_UNALIGNED_ATOMIC] =
+                               rdev->stats.res_unaligned_atomic;
+               stats->value[BNXT_RE_RES_REM_INV_ERR]   =
+                               rdev->stats.res_rem_inv_err;
+               stats->value[BNXT_RE_RES_MEM_ERROR] =
+                               rdev->stats.res_mem_error;
+               stats->value[BNXT_RE_RES_SRQ_ERR] =
+                               rdev->stats.res_srq_err;
+               stats->value[BNXT_RE_RES_CMP_ERR] =
+                               rdev->stats.res_cmp_err;
+               stats->value[BNXT_RE_RES_INVALID_DUP_RKEY] =
+                               rdev->stats.res_invalid_dup_rkey;
+               stats->value[BNXT_RE_RES_WQE_FORMAT_ERR] =
+                               rdev->stats.res_wqe_format_err;
+               stats->value[BNXT_RE_RES_CQ_LOAD_ERR]   =
+                               rdev->stats.res_cq_load_err;
+               stats->value[BNXT_RE_RES_SRQ_LOAD_ERR]  =
+                               rdev->stats.res_srq_load_err;
+               stats->value[BNXT_RE_RES_TX_PCI_ERR]    =
+                               rdev->stats.res_tx_pci_err;
+               stats->value[BNXT_RE_RES_RX_PCI_ERR]    =
+                               rdev->stats.res_rx_pci_err;
+       }
+
        return ARRAY_SIZE(bnxt_re_stat_name);
 }
 
index be0dc0093b58248b0c742bfa5278065cc77ce8ef..a01a922717d5c138b45e49c0832564387402e3f5 100644 (file)
@@ -51,6 +51,45 @@ enum bnxt_re_hw_stats {
        BNXT_RE_TX_PKTS,
        BNXT_RE_TX_BYTES,
        BNXT_RE_RECOVERABLE_ERRORS,
+       BNXT_RE_TO_RETRANSMITS,
+       BNXT_RE_SEQ_ERR_NAKS_RCVD,
+       BNXT_RE_MAX_RETRY_EXCEEDED,
+       BNXT_RE_RNR_NAKS_RCVD,
+       BNXT_RE_MISSING_RESP,
+       BNXT_RE_UNRECOVERABLE_ERR,
+       BNXT_RE_BAD_RESP_ERR,
+       BNXT_RE_LOCAL_QP_OP_ERR,
+       BNXT_RE_LOCAL_PROTECTION_ERR,
+       BNXT_RE_MEM_MGMT_OP_ERR,
+       BNXT_RE_REMOTE_INVALID_REQ_ERR,
+       BNXT_RE_REMOTE_ACCESS_ERR,
+       BNXT_RE_REMOTE_OP_ERR,
+       BNXT_RE_DUP_REQ,
+       BNXT_RE_RES_EXCEED_MAX,
+       BNXT_RE_RES_LENGTH_MISMATCH,
+       BNXT_RE_RES_EXCEEDS_WQE,
+       BNXT_RE_RES_OPCODE_ERR,
+       BNXT_RE_RES_RX_INVALID_RKEY,
+       BNXT_RE_RES_RX_DOMAIN_ERR,
+       BNXT_RE_RES_RX_NO_PERM,
+       BNXT_RE_RES_RX_RANGE_ERR,
+       BNXT_RE_RES_TX_INVALID_RKEY,
+       BNXT_RE_RES_TX_DOMAIN_ERR,
+       BNXT_RE_RES_TX_NO_PERM,
+       BNXT_RE_RES_TX_RANGE_ERR,
+       BNXT_RE_RES_IRRQ_OFLOW,
+       BNXT_RE_RES_UNSUP_OPCODE,
+       BNXT_RE_RES_UNALIGNED_ATOMIC,
+       BNXT_RE_RES_REM_INV_ERR,
+       BNXT_RE_RES_MEM_ERROR,
+       BNXT_RE_RES_SRQ_ERR,
+       BNXT_RE_RES_CMP_ERR,
+       BNXT_RE_RES_INVALID_DUP_RKEY,
+       BNXT_RE_RES_WQE_FORMAT_ERR,
+       BNXT_RE_RES_CQ_LOAD_ERR,
+       BNXT_RE_RES_SRQ_LOAD_ERR,
+       BNXT_RE_RES_TX_PCI_ERR,
+       BNXT_RE_RES_RX_PCI_ERR,
        BNXT_RE_NUM_COUNTERS
 };
 
index ca1195024e9b3f9841287e391e4988d6e7bce206..3caf70a103e693eb521d5d1610fa97e54147e273 100644 (file)
@@ -1245,6 +1245,7 @@ static int bnxt_re_ib_reg(struct bnxt_re_dev *rdev)
        set_bit(BNXT_RE_FLAG_IBDEV_REGISTERED, &rdev->flags);
        ib_get_eth_speed(&rdev->ibdev, 1, &rdev->active_speed,
                         &rdev->active_width);
+       set_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags);
        bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_PORT_ACTIVE);
        bnxt_re_dispatch_event(&rdev->ibdev, NULL, 1, IB_EVENT_GID_CHANGE);
 
index e71bc57a1f3a12d1cbfd8cbe71849499b812e976..c015c1861351ae91d1455b97ee493a97e5ee5645 100644 (file)
@@ -790,3 +790,73 @@ int bnxt_qplib_map_tc2cos(struct bnxt_qplib_res *res, u16 *cids)
                                     0);
        return 0;
 }
+
+int bnxt_qplib_get_roce_stats(struct bnxt_qplib_rcfw *rcfw,
+                             struct bnxt_qplib_roce_stats *stats)
+{
+       struct cmdq_query_roce_stats req;
+       struct creq_query_roce_stats_resp resp;
+       struct bnxt_qplib_rcfw_sbuf *sbuf;
+       struct creq_query_roce_stats_resp_sb *sb;
+       u16 cmd_flags = 0;
+       int rc = 0;
+
+       RCFW_CMD_PREP(req, QUERY_ROCE_STATS, cmd_flags);
+
+       sbuf = bnxt_qplib_rcfw_alloc_sbuf(rcfw, sizeof(*sb));
+       if (!sbuf) {
+               dev_err(&rcfw->pdev->dev,
+                       "QPLIB: SP: QUERY_ROCE_STATS alloc side buffer failed");
+               return -ENOMEM;
+       }
+
+       sb = sbuf->sb;
+       req.resp_size = sizeof(*sb) / BNXT_QPLIB_CMDQE_UNITS;
+       rc = bnxt_qplib_rcfw_send_message(rcfw, (void *)&req, (void *)&resp,
+                                         (void *)sbuf, 0);
+       if (rc)
+               goto bail;
+       /* Extract the context from the side buffer */
+       stats->to_retransmits = le64_to_cpu(sb->to_retransmits);
+       stats->seq_err_naks_rcvd = le64_to_cpu(sb->seq_err_naks_rcvd);
+       stats->max_retry_exceeded = le64_to_cpu(sb->max_retry_exceeded);
+       stats->rnr_naks_rcvd = le64_to_cpu(sb->rnr_naks_rcvd);
+       stats->missing_resp = le64_to_cpu(sb->missing_resp);
+       stats->unrecoverable_err = le64_to_cpu(sb->unrecoverable_err);
+       stats->bad_resp_err = le64_to_cpu(sb->bad_resp_err);
+       stats->local_qp_op_err = le64_to_cpu(sb->local_qp_op_err);
+       stats->local_protection_err = le64_to_cpu(sb->local_protection_err);
+       stats->mem_mgmt_op_err = le64_to_cpu(sb->mem_mgmt_op_err);
+       stats->remote_invalid_req_err = le64_to_cpu(sb->remote_invalid_req_err);
+       stats->remote_access_err = le64_to_cpu(sb->remote_access_err);
+       stats->remote_op_err = le64_to_cpu(sb->remote_op_err);
+       stats->dup_req = le64_to_cpu(sb->dup_req);
+       stats->res_exceed_max = le64_to_cpu(sb->res_exceed_max);
+       stats->res_length_mismatch = le64_to_cpu(sb->res_length_mismatch);
+       stats->res_exceeds_wqe = le64_to_cpu(sb->res_exceeds_wqe);
+       stats->res_opcode_err = le64_to_cpu(sb->res_opcode_err);
+       stats->res_rx_invalid_rkey = le64_to_cpu(sb->res_rx_invalid_rkey);
+       stats->res_rx_domain_err = le64_to_cpu(sb->res_rx_domain_err);
+       stats->res_rx_no_perm = le64_to_cpu(sb->res_rx_no_perm);
+       stats->res_rx_range_err = le64_to_cpu(sb->res_rx_range_err);
+       stats->res_tx_invalid_rkey = le64_to_cpu(sb->res_tx_invalid_rkey);
+       stats->res_tx_domain_err = le64_to_cpu(sb->res_tx_domain_err);
+       stats->res_tx_no_perm = le64_to_cpu(sb->res_tx_no_perm);
+       stats->res_tx_range_err = le64_to_cpu(sb->res_tx_range_err);
+       stats->res_irrq_oflow = le64_to_cpu(sb->res_irrq_oflow);
+       stats->res_unsup_opcode = le64_to_cpu(sb->res_unsup_opcode);
+       stats->res_unaligned_atomic = le64_to_cpu(sb->res_unaligned_atomic);
+       stats->res_rem_inv_err = le64_to_cpu(sb->res_rem_inv_err);
+       stats->res_mem_error = le64_to_cpu(sb->res_mem_error);
+       stats->res_srq_err = le64_to_cpu(sb->res_srq_err);
+       stats->res_cmp_err = le64_to_cpu(sb->res_cmp_err);
+       stats->res_invalid_dup_rkey = le64_to_cpu(sb->res_invalid_dup_rkey);
+       stats->res_wqe_format_err = le64_to_cpu(sb->res_wqe_format_err);
+       stats->res_cq_load_err = le64_to_cpu(sb->res_cq_load_err);
+       stats->res_srq_load_err = le64_to_cpu(sb->res_srq_load_err);
+       stats->res_tx_pci_err = le64_to_cpu(sb->res_tx_pci_err);
+       stats->res_rx_pci_err = le64_to_cpu(sb->res_rx_pci_err);
+bail:
+       bnxt_qplib_rcfw_free_sbuf(rcfw, sbuf);
+       return rc;
+}
index 074e5e3253492805cc298412eafaefb8641e16c2..9d3e8b9949458a4503d6ee942f8abe324c90954e 100644 (file)
@@ -128,6 +128,85 @@ struct bnxt_qplib_frpl {
 #define BNXT_QPLIB_ACCESS_ZERO_BASED   BIT(5)
 #define BNXT_QPLIB_ACCESS_ON_DEMAND    BIT(6)
 
+struct bnxt_qplib_roce_stats {
+       u64 to_retransmits;
+       u64 seq_err_naks_rcvd;
+       /* seq_err_naks_rcvd is 64 b */
+       u64 max_retry_exceeded;
+       /* max_retry_exceeded is 64 b */
+       u64 rnr_naks_rcvd;
+       /* rnr_naks_rcvd is 64 b */
+       u64 missing_resp;
+       u64 unrecoverable_err;
+       /* unrecoverable_err is 64 b */
+       u64 bad_resp_err;
+       /* bad_resp_err is 64 b */
+       u64 local_qp_op_err;
+       /* local_qp_op_err is 64 b */
+       u64 local_protection_err;
+       /* local_protection_err is 64 b */
+       u64 mem_mgmt_op_err;
+       /* mem_mgmt_op_err is 64 b */
+       u64 remote_invalid_req_err;
+       /* remote_invalid_req_err is 64 b */
+       u64 remote_access_err;
+       /* remote_access_err is 64 b */
+       u64 remote_op_err;
+       /* remote_op_err is 64 b */
+       u64 dup_req;
+       /* dup_req is 64 b */
+       u64 res_exceed_max;
+       /* res_exceed_max is 64 b */
+       u64 res_length_mismatch;
+       /* res_length_mismatch is 64 b */
+       u64 res_exceeds_wqe;
+       /* res_exceeds_wqe is 64 b */
+       u64 res_opcode_err;
+       /* res_opcode_err is 64 b */
+       u64 res_rx_invalid_rkey;
+       /* res_rx_invalid_rkey is 64 b */
+       u64 res_rx_domain_err;
+       /* res_rx_domain_err is 64 b */
+       u64 res_rx_no_perm;
+       /* res_rx_no_perm is 64 b */
+       u64 res_rx_range_err;
+       /* res_rx_range_err is 64 b */
+       u64 res_tx_invalid_rkey;
+       /* res_tx_invalid_rkey is 64 b */
+       u64 res_tx_domain_err;
+       /* res_tx_domain_err is 64 b */
+       u64 res_tx_no_perm;
+       /* res_tx_no_perm is 64 b */
+       u64 res_tx_range_err;
+       /* res_tx_range_err is 64 b */
+       u64 res_irrq_oflow;
+       /* res_irrq_oflow is 64 b */
+       u64 res_unsup_opcode;
+       /* res_unsup_opcode is 64 b */
+       u64 res_unaligned_atomic;
+       /* res_unaligned_atomic is 64 b */
+       u64 res_rem_inv_err;
+       /* res_rem_inv_err is 64 b */
+       u64 res_mem_error;
+       /* res_mem_error is 64 b */
+       u64 res_srq_err;
+       /* res_srq_err is 64 b */
+       u64 res_cmp_err;
+       /* res_cmp_err is 64 b */
+       u64 res_invalid_dup_rkey;
+       /* res_invalid_dup_rkey is 64 b */
+       u64 res_wqe_format_err;
+       /* res_wqe_format_err is 64 b */
+       u64 res_cq_load_err;
+       /* res_cq_load_err is 64 b */
+       u64 res_srq_load_err;
+       /* res_srq_load_err is 64 b */
+       u64 res_tx_pci_err;
+       /* res_tx_pci_err is 64 b */
+       u64 res_rx_pci_err;
+       /* res_rx_pci_err is 64 b */
+};
+
 int bnxt_qplib_get_sgid(struct bnxt_qplib_res *res,
                        struct bnxt_qplib_sgid_tbl *sgid_tbl, int index,
                        struct bnxt_qplib_gid *gid);
@@ -168,4 +247,6 @@ int bnxt_qplib_alloc_fast_reg_page_list(struct bnxt_qplib_res *res,
 int bnxt_qplib_free_fast_reg_page_list(struct bnxt_qplib_res *res,
                                       struct bnxt_qplib_frpl *frpl);
 int bnxt_qplib_map_tc2cos(struct bnxt_qplib_res *res, u16 *cids);
+int bnxt_qplib_get_roce_stats(struct bnxt_qplib_rcfw *rcfw,
+                             struct bnxt_qplib_roce_stats *stats);
 #endif /* __BNXT_QPLIB_SP_H__*/
index 5cd31de223304207fdbaf6a2d9e00971037e36af..2d7ea096a247478392acf58b4a234112ea35f54a 100644 (file)
@@ -954,6 +954,7 @@ struct cmdq_base {
        #define CMDQ_BASE_OPCODE_QUERY_VERSION                     0x8bUL
        #define CMDQ_BASE_OPCODE_MODIFY_CC                         0x8cUL
        #define CMDQ_BASE_OPCODE_QUERY_CC                          0x8dUL
+       #define CMDQ_BASE_OPCODE_QUERY_ROCE_STATS          0x8eUL
        u8 cmd_size;
        __le16 flags;
        __le16 cookie;
@@ -2049,6 +2050,20 @@ struct creq_modify_qp_resp {
        __le16 reserved48[3];
 };
 
+/* cmdq_query_roce_stats (size:128b/16B) */
+struct cmdq_query_roce_stats {
+       u8      opcode;
+       #define CMDQ_QUERY_ROCE_STATS_OPCODE_QUERY_ROCE_STATS 0x8eUL
+       #define CMDQ_QUERY_ROCE_STATS_OPCODE_LAST       \
+                               CMDQ_QUERY_ROCE_STATS_OPCODE_QUERY_ROCE_STATS
+       u8      cmd_size;
+       __le16  flags;
+       __le16  cookie;
+       u8      resp_size;
+       u8      reserved8;
+       __le64  resp_addr;
+};
+
 /* Query QP command response (16 bytes) */
 struct creq_query_qp_resp {
        u8 type;
@@ -2819,6 +2834,80 @@ struct creq_query_cc_resp_sb {
        __le64 reserved64_1;
 };
 
+/* creq_query_roce_stats_resp (size:128b/16B) */
+struct creq_query_roce_stats_resp {
+       u8      type;
+       #define CREQ_QUERY_ROCE_STATS_RESP_TYPE_MASK    0x3fUL
+       #define CREQ_QUERY_ROCE_STATS_RESP_TYPE_SFT     0
+       #define CREQ_QUERY_ROCE_STATS_RESP_TYPE_QP_EVENT  0x38UL
+       #define CREQ_QUERY_ROCE_STATS_RESP_TYPE_LAST    \
+                               CREQ_QUERY_ROCE_STATS_RESP_TYPE_QP_EVENT
+       u8      status;
+       __le16  cookie;
+       __le32  size;
+       u8      v;
+       #define CREQ_QUERY_ROCE_STATS_RESP_V     0x1UL
+       u8      event;
+       #define CREQ_QUERY_ROCE_STATS_RESP_EVENT_QUERY_ROCE_STATS 0x8eUL
+       #define CREQ_QUERY_ROCE_STATS_RESP_EVENT_LAST   \
+                       CREQ_QUERY_ROCE_STATS_RESP_EVENT_QUERY_ROCE_STATS
+       u8      reserved48[6];
+};
+
+/* creq_query_roce_stats_resp_sb (size:2624b/328B) */
+struct creq_query_roce_stats_resp_sb {
+       u8      opcode;
+       #define CREQ_QUERY_ROCE_STATS_RESP_SB_OPCODE_QUERY_ROCE_STATS 0x8eUL
+       #define CREQ_QUERY_ROCE_STATS_RESP_SB_OPCODE_LAST \
+                       CREQ_QUERY_ROCE_STATS_RESP_SB_OPCODE_QUERY_ROCE_STATS
+       u8      status;
+       __le16  cookie;
+       __le16  flags;
+       u8      resp_size;
+       u8      rsvd;
+       __le32  num_counters;
+       __le32  rsvd1;
+       __le64  to_retransmits;
+       __le64  seq_err_naks_rcvd;
+       __le64  max_retry_exceeded;
+       __le64  rnr_naks_rcvd;
+       __le64  missing_resp;
+       __le64  unrecoverable_err;
+       __le64  bad_resp_err;
+       __le64  local_qp_op_err;
+       __le64  local_protection_err;
+       __le64  mem_mgmt_op_err;
+       __le64  remote_invalid_req_err;
+       __le64  remote_access_err;
+       __le64  remote_op_err;
+       __le64  dup_req;
+       __le64  res_exceed_max;
+       __le64  res_length_mismatch;
+       __le64  res_exceeds_wqe;
+       __le64  res_opcode_err;
+       __le64  res_rx_invalid_rkey;
+       __le64  res_rx_domain_err;
+       __le64  res_rx_no_perm;
+       __le64  res_rx_range_err;
+       __le64  res_tx_invalid_rkey;
+       __le64  res_tx_domain_err;
+       __le64  res_tx_no_perm;
+       __le64  res_tx_range_err;
+       __le64  res_irrq_oflow;
+       __le64  res_unsup_opcode;
+       __le64  res_unaligned_atomic;
+       __le64  res_rem_inv_err;
+       __le64  res_mem_error;
+       __le64  res_srq_err;
+       __le64  res_cmp_err;
+       __le64  res_invalid_dup_rkey;
+       __le64  res_wqe_format_err;
+       __le64  res_cq_load_err;
+       __le64  res_srq_load_err;
+       __le64  res_tx_pci_err;
+       __le64  res_rx_pci_err;
+};
+
 /* QP error notification event (16 bytes) */
 struct creq_qp_error_notification {
        u8 type;