Back to home page

OSCL-LXR

 
 

    


0001 /*
0002  * Broadcom NetXtreme-E RoCE driver.
0003  *
0004  * Copyright (c) 2016 - 2017, Broadcom. All rights reserved.  The term
0005  * Broadcom refers to Broadcom Limited and/or its subsidiaries.
0006  *
0007  * This software is available to you under a choice of one of two
0008  * licenses.  You may choose to be licensed under the terms of the GNU
0009  * General Public License (GPL) Version 2, available from the file
0010  * COPYING in the main directory of this source tree, or the
0011  * BSD license below:
0012  *
0013  * Redistribution and use in source and binary forms, with or without
0014  * modification, are permitted provided that the following conditions
0015  * are met:
0016  *
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in
0021  *    the documentation and/or other materials provided with the
0022  *    distribution.
0023  *
0024  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS''
0025  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
0026  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0027  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
0028  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0029  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0030  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
0031  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
0032  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
0033  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
0034  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0035  *
0036  * Description: Statistics
0037  *
0038  */
0039 
0040 #include <linux/interrupt.h>
0041 #include <linux/types.h>
0042 #include <linux/spinlock.h>
0043 #include <linux/sched.h>
0044 #include <linux/slab.h>
0045 #include <linux/pci.h>
0046 #include <linux/prefetch.h>
0047 #include <linux/delay.h>
0048 
0049 #include <rdma/ib_addr.h>
0050 
0051 #include "bnxt_ulp.h"
0052 #include "roce_hsi.h"
0053 #include "qplib_res.h"
0054 #include "qplib_sp.h"
0055 #include "qplib_fp.h"
0056 #include "qplib_rcfw.h"
0057 #include "bnxt_re.h"
0058 #include "hw_counters.h"
0059 
0060 static const struct rdma_stat_desc bnxt_re_stat_descs[] = {
0061     [BNXT_RE_ACTIVE_PD].name        =  "active_pds",
0062     [BNXT_RE_ACTIVE_AH].name        =  "active_ahs",
0063     [BNXT_RE_ACTIVE_QP].name        =  "active_qps",
0064     [BNXT_RE_ACTIVE_SRQ].name       =  "active_srqs",
0065     [BNXT_RE_ACTIVE_CQ].name        =  "active_cqs",
0066     [BNXT_RE_ACTIVE_MR].name        =  "active_mrs",
0067     [BNXT_RE_ACTIVE_MW].name        =  "active_mws",
0068     [BNXT_RE_RX_PKTS].name      =  "rx_pkts",
0069     [BNXT_RE_RX_BYTES].name     =  "rx_bytes",
0070     [BNXT_RE_TX_PKTS].name      =  "tx_pkts",
0071     [BNXT_RE_TX_BYTES].name     =  "tx_bytes",
0072     [BNXT_RE_RECOVERABLE_ERRORS].name   =  "recoverable_errors",
0073     [BNXT_RE_RX_ERRORS].name        =  "rx_roce_errors",
0074     [BNXT_RE_RX_DISCARDS].name      =  "rx_roce_discards",
0075     [BNXT_RE_TO_RETRANSMITS].name        = "to_retransmits",
0076     [BNXT_RE_SEQ_ERR_NAKS_RCVD].name     = "seq_err_naks_rcvd",
0077     [BNXT_RE_MAX_RETRY_EXCEEDED].name    = "max_retry_exceeded",
0078     [BNXT_RE_RNR_NAKS_RCVD].name         = "rnr_naks_rcvd",
0079     [BNXT_RE_MISSING_RESP].name          = "missing_resp",
0080     [BNXT_RE_UNRECOVERABLE_ERR].name     = "unrecoverable_err",
0081     [BNXT_RE_BAD_RESP_ERR].name          = "bad_resp_err",
0082     [BNXT_RE_LOCAL_QP_OP_ERR].name       = "local_qp_op_err",
0083     [BNXT_RE_LOCAL_PROTECTION_ERR].name  = "local_protection_err",
0084     [BNXT_RE_MEM_MGMT_OP_ERR].name       = "mem_mgmt_op_err",
0085     [BNXT_RE_REMOTE_INVALID_REQ_ERR].name = "remote_invalid_req_err",
0086     [BNXT_RE_REMOTE_ACCESS_ERR].name     = "remote_access_err",
0087     [BNXT_RE_REMOTE_OP_ERR].name         = "remote_op_err",
0088     [BNXT_RE_DUP_REQ].name               = "dup_req",
0089     [BNXT_RE_RES_EXCEED_MAX].name        = "res_exceed_max",
0090     [BNXT_RE_RES_LENGTH_MISMATCH].name   = "res_length_mismatch",
0091     [BNXT_RE_RES_EXCEEDS_WQE].name       = "res_exceeds_wqe",
0092     [BNXT_RE_RES_OPCODE_ERR].name        = "res_opcode_err",
0093     [BNXT_RE_RES_RX_INVALID_RKEY].name   = "res_rx_invalid_rkey",
0094     [BNXT_RE_RES_RX_DOMAIN_ERR].name     = "res_rx_domain_err",
0095     [BNXT_RE_RES_RX_NO_PERM].name        = "res_rx_no_perm",
0096     [BNXT_RE_RES_RX_RANGE_ERR].name      = "res_rx_range_err",
0097     [BNXT_RE_RES_TX_INVALID_RKEY].name   = "res_tx_invalid_rkey",
0098     [BNXT_RE_RES_TX_DOMAIN_ERR].name     = "res_tx_domain_err",
0099     [BNXT_RE_RES_TX_NO_PERM].name        = "res_tx_no_perm",
0100     [BNXT_RE_RES_TX_RANGE_ERR].name      = "res_tx_range_err",
0101     [BNXT_RE_RES_IRRQ_OFLOW].name        = "res_irrq_oflow",
0102     [BNXT_RE_RES_UNSUP_OPCODE].name      = "res_unsup_opcode",
0103     [BNXT_RE_RES_UNALIGNED_ATOMIC].name  = "res_unaligned_atomic",
0104     [BNXT_RE_RES_REM_INV_ERR].name       = "res_rem_inv_err",
0105     [BNXT_RE_RES_MEM_ERROR].name         = "res_mem_err",
0106     [BNXT_RE_RES_SRQ_ERR].name           = "res_srq_err",
0107     [BNXT_RE_RES_CMP_ERR].name           = "res_cmp_err",
0108     [BNXT_RE_RES_INVALID_DUP_RKEY].name  = "res_invalid_dup_rkey",
0109     [BNXT_RE_RES_WQE_FORMAT_ERR].name    = "res_wqe_format_err",
0110     [BNXT_RE_RES_CQ_LOAD_ERR].name       = "res_cq_load_err",
0111     [BNXT_RE_RES_SRQ_LOAD_ERR].name      = "res_srq_load_err",
0112     [BNXT_RE_RES_TX_PCI_ERR].name        = "res_tx_pci_err",
0113     [BNXT_RE_RES_RX_PCI_ERR].name        = "res_rx_pci_err",
0114     [BNXT_RE_OUT_OF_SEQ_ERR].name        = "oos_drop_count",
0115     [BNXT_RE_TX_ATOMIC_REQ].name         = "tx_atomic_req",
0116     [BNXT_RE_TX_READ_REQ].name       = "tx_read_req",
0117     [BNXT_RE_TX_READ_RES].name       = "tx_read_resp",
0118     [BNXT_RE_TX_WRITE_REQ].name      = "tx_write_req",
0119     [BNXT_RE_TX_SEND_REQ].name       = "tx_send_req",
0120     [BNXT_RE_RX_ATOMIC_REQ].name         = "rx_atomic_req",
0121     [BNXT_RE_RX_READ_REQ].name       = "rx_read_req",
0122     [BNXT_RE_RX_READ_RESP].name      = "rx_read_resp",
0123     [BNXT_RE_RX_WRITE_REQ].name      = "rx_write_req",
0124     [BNXT_RE_RX_SEND_REQ].name       = "rx_send_req",
0125     [BNXT_RE_RX_ROCE_GOOD_PKTS].name     = "rx_roce_good_pkts",
0126     [BNXT_RE_RX_ROCE_GOOD_BYTES].name    = "rx_roce_good_bytes",
0127     [BNXT_RE_OOB].name           = "rx_out_of_buffer"
0128 };
0129 
0130 static void bnxt_re_copy_ext_stats(struct bnxt_re_dev *rdev,
0131                    struct rdma_hw_stats *stats,
0132                    struct bnxt_qplib_ext_stat *s)
0133 {
0134     stats->value[BNXT_RE_TX_ATOMIC_REQ] = s->tx_atomic_req;
0135     stats->value[BNXT_RE_TX_READ_REQ]   = s->tx_read_req;
0136     stats->value[BNXT_RE_TX_READ_RES]   = s->tx_read_res;
0137     stats->value[BNXT_RE_TX_WRITE_REQ]  = s->tx_write_req;
0138     stats->value[BNXT_RE_TX_SEND_REQ]   = s->tx_send_req;
0139     stats->value[BNXT_RE_RX_ATOMIC_REQ] = s->rx_atomic_req;
0140     stats->value[BNXT_RE_RX_READ_REQ]   = s->rx_read_req;
0141     stats->value[BNXT_RE_RX_READ_RESP]  = s->rx_read_res;
0142     stats->value[BNXT_RE_RX_WRITE_REQ]  = s->rx_write_req;
0143     stats->value[BNXT_RE_RX_SEND_REQ]   = s->rx_send_req;
0144     stats->value[BNXT_RE_RX_ROCE_GOOD_PKTS] = s->rx_roce_good_pkts;
0145     stats->value[BNXT_RE_RX_ROCE_GOOD_BYTES] = s->rx_roce_good_bytes;
0146     stats->value[BNXT_RE_OOB] = s->rx_out_of_buffer;
0147 }
0148 
0149 static int bnxt_re_get_ext_stat(struct bnxt_re_dev *rdev,
0150                 struct rdma_hw_stats *stats)
0151 {
0152     struct bnxt_qplib_ext_stat *estat = &rdev->stats.rstat.ext_stat;
0153     u32 fid;
0154     int rc;
0155 
0156     fid = PCI_FUNC(rdev->en_dev->pdev->devfn);
0157     rc = bnxt_qplib_qext_stat(&rdev->rcfw, fid, estat);
0158     if (rc)
0159         goto done;
0160     bnxt_re_copy_ext_stats(rdev, stats, estat);
0161 
0162 done:
0163     return rc;
0164 }
0165 
0166 static void bnxt_re_copy_err_stats(struct bnxt_re_dev *rdev,
0167                    struct rdma_hw_stats *stats,
0168                    struct bnxt_qplib_roce_stats *err_s)
0169 {
0170     stats->value[BNXT_RE_TO_RETRANSMITS] =
0171                 err_s->to_retransmits;
0172     stats->value[BNXT_RE_SEQ_ERR_NAKS_RCVD] =
0173                 err_s->seq_err_naks_rcvd;
0174     stats->value[BNXT_RE_MAX_RETRY_EXCEEDED] =
0175                 err_s->max_retry_exceeded;
0176     stats->value[BNXT_RE_RNR_NAKS_RCVD] =
0177                 err_s->rnr_naks_rcvd;
0178     stats->value[BNXT_RE_MISSING_RESP] =
0179                 err_s->missing_resp;
0180     stats->value[BNXT_RE_UNRECOVERABLE_ERR] =
0181                 err_s->unrecoverable_err;
0182     stats->value[BNXT_RE_BAD_RESP_ERR] =
0183                 err_s->bad_resp_err;
0184     stats->value[BNXT_RE_LOCAL_QP_OP_ERR]   =
0185             err_s->local_qp_op_err;
0186     stats->value[BNXT_RE_LOCAL_PROTECTION_ERR] =
0187             err_s->local_protection_err;
0188     stats->value[BNXT_RE_MEM_MGMT_OP_ERR] =
0189             err_s->mem_mgmt_op_err;
0190     stats->value[BNXT_RE_REMOTE_INVALID_REQ_ERR] =
0191             err_s->remote_invalid_req_err;
0192     stats->value[BNXT_RE_REMOTE_ACCESS_ERR] =
0193             err_s->remote_access_err;
0194     stats->value[BNXT_RE_REMOTE_OP_ERR] =
0195             err_s->remote_op_err;
0196     stats->value[BNXT_RE_DUP_REQ] =
0197             err_s->dup_req;
0198     stats->value[BNXT_RE_RES_EXCEED_MAX] =
0199             err_s->res_exceed_max;
0200     stats->value[BNXT_RE_RES_LENGTH_MISMATCH] =
0201             err_s->res_length_mismatch;
0202     stats->value[BNXT_RE_RES_EXCEEDS_WQE] =
0203             err_s->res_exceeds_wqe;
0204     stats->value[BNXT_RE_RES_OPCODE_ERR] =
0205             err_s->res_opcode_err;
0206     stats->value[BNXT_RE_RES_RX_INVALID_RKEY] =
0207             err_s->res_rx_invalid_rkey;
0208     stats->value[BNXT_RE_RES_RX_DOMAIN_ERR] =
0209             err_s->res_rx_domain_err;
0210     stats->value[BNXT_RE_RES_RX_NO_PERM] =
0211             err_s->res_rx_no_perm;
0212     stats->value[BNXT_RE_RES_RX_RANGE_ERR]  =
0213             err_s->res_rx_range_err;
0214     stats->value[BNXT_RE_RES_TX_INVALID_RKEY] =
0215             err_s->res_tx_invalid_rkey;
0216     stats->value[BNXT_RE_RES_TX_DOMAIN_ERR] =
0217             err_s->res_tx_domain_err;
0218     stats->value[BNXT_RE_RES_TX_NO_PERM] =
0219             err_s->res_tx_no_perm;
0220     stats->value[BNXT_RE_RES_TX_RANGE_ERR]  =
0221             err_s->res_tx_range_err;
0222     stats->value[BNXT_RE_RES_IRRQ_OFLOW] =
0223             err_s->res_irrq_oflow;
0224     stats->value[BNXT_RE_RES_UNSUP_OPCODE]  =
0225             err_s->res_unsup_opcode;
0226     stats->value[BNXT_RE_RES_UNALIGNED_ATOMIC] =
0227             err_s->res_unaligned_atomic;
0228     stats->value[BNXT_RE_RES_REM_INV_ERR]   =
0229             err_s->res_rem_inv_err;
0230     stats->value[BNXT_RE_RES_MEM_ERROR] =
0231             err_s->res_mem_error;
0232     stats->value[BNXT_RE_RES_SRQ_ERR] =
0233             err_s->res_srq_err;
0234     stats->value[BNXT_RE_RES_CMP_ERR] =
0235             err_s->res_cmp_err;
0236     stats->value[BNXT_RE_RES_INVALID_DUP_RKEY] =
0237             err_s->res_invalid_dup_rkey;
0238     stats->value[BNXT_RE_RES_WQE_FORMAT_ERR] =
0239             err_s->res_wqe_format_err;
0240     stats->value[BNXT_RE_RES_CQ_LOAD_ERR]   =
0241             err_s->res_cq_load_err;
0242     stats->value[BNXT_RE_RES_SRQ_LOAD_ERR]  =
0243             err_s->res_srq_load_err;
0244     stats->value[BNXT_RE_RES_TX_PCI_ERR]    =
0245             err_s->res_tx_pci_err;
0246     stats->value[BNXT_RE_RES_RX_PCI_ERR]    =
0247             err_s->res_rx_pci_err;
0248     stats->value[BNXT_RE_OUT_OF_SEQ_ERR]    =
0249             err_s->res_oos_drop_count;
0250 }
0251 
0252 int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev,
0253                 struct rdma_hw_stats *stats,
0254                 u32 port, int index)
0255 {
0256     struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
0257     struct ctx_hw_stats *hw_stats = NULL;
0258     struct bnxt_qplib_roce_stats *err_s = NULL;
0259     int rc  = 0;
0260 
0261     hw_stats = rdev->qplib_ctx.stats.dma;
0262     if (!port || !stats)
0263         return -EINVAL;
0264 
0265     stats->value[BNXT_RE_ACTIVE_QP] = atomic_read(&rdev->qp_count);
0266     stats->value[BNXT_RE_ACTIVE_SRQ] = atomic_read(&rdev->srq_count);
0267     stats->value[BNXT_RE_ACTIVE_CQ] = atomic_read(&rdev->cq_count);
0268     stats->value[BNXT_RE_ACTIVE_MR] = atomic_read(&rdev->mr_count);
0269     stats->value[BNXT_RE_ACTIVE_MW] = atomic_read(&rdev->mw_count);
0270     stats->value[BNXT_RE_ACTIVE_PD] = atomic_read(&rdev->pd_count);
0271     stats->value[BNXT_RE_ACTIVE_AH] = atomic_read(&rdev->ah_count);
0272 
0273     if (hw_stats) {
0274         stats->value[BNXT_RE_RECOVERABLE_ERRORS] =
0275             le64_to_cpu(hw_stats->tx_bcast_pkts);
0276         stats->value[BNXT_RE_RX_ERRORS] =
0277             le64_to_cpu(hw_stats->rx_error_pkts);
0278         stats->value[BNXT_RE_RX_DISCARDS] =
0279             le64_to_cpu(hw_stats->rx_discard_pkts);
0280         stats->value[BNXT_RE_RX_PKTS] =
0281             le64_to_cpu(hw_stats->rx_ucast_pkts);
0282         stats->value[BNXT_RE_RX_BYTES] =
0283             le64_to_cpu(hw_stats->rx_ucast_bytes);
0284         stats->value[BNXT_RE_TX_PKTS] =
0285             le64_to_cpu(hw_stats->tx_ucast_pkts);
0286         stats->value[BNXT_RE_TX_BYTES] =
0287             le64_to_cpu(hw_stats->tx_ucast_bytes);
0288     }
0289     err_s = &rdev->stats.rstat.errs;
0290     if (test_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS, &rdev->flags)) {
0291         rc = bnxt_qplib_get_roce_stats(&rdev->rcfw, err_s);
0292         if (rc) {
0293             clear_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS,
0294                   &rdev->flags);
0295             goto done;
0296         }
0297         if (_is_ext_stats_supported(rdev->dev_attr.dev_cap_flags) &&
0298             !rdev->is_virtfn) {
0299             rc = bnxt_re_get_ext_stat(rdev, stats);
0300             if (rc) {
0301                 clear_bit(BNXT_RE_FLAG_ISSUE_ROCE_STATS,
0302                       &rdev->flags);
0303                 goto done;
0304             }
0305         }
0306         bnxt_re_copy_err_stats(rdev, stats, err_s);
0307     }
0308 
0309 done:
0310     return bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx) ?
0311         BNXT_RE_NUM_EXT_COUNTERS : BNXT_RE_NUM_STD_COUNTERS;
0312 }
0313 
0314 struct rdma_hw_stats *bnxt_re_ib_alloc_hw_port_stats(struct ib_device *ibdev,
0315                              u32 port_num)
0316 {
0317     struct bnxt_re_dev *rdev = to_bnxt_re_dev(ibdev, ibdev);
0318     int num_counters = 0;
0319 
0320     if (bnxt_qplib_is_chip_gen_p5(rdev->chip_ctx))
0321         num_counters = BNXT_RE_NUM_EXT_COUNTERS;
0322     else
0323         num_counters = BNXT_RE_NUM_STD_COUNTERS;
0324 
0325     return rdma_alloc_hw_stats_struct(bnxt_re_stat_descs, num_counters,
0326                       RDMA_HW_STATS_DEFAULT_LIFESPAN);
0327 }