0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
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 }