1*9207f9d2SChandrakanth patil /* 2*9207f9d2SChandrakanth patil * Copyright (c) 2024, Broadcom. All rights reserved. The term 3*9207f9d2SChandrakanth patil * Broadcom refers to Broadcom Limited and/or its subsidiaries. 4*9207f9d2SChandrakanth patil * 5*9207f9d2SChandrakanth patil * Redistribution and use in source and binary forms, with or without 6*9207f9d2SChandrakanth patil * modification, are permitted provided that the following conditions 7*9207f9d2SChandrakanth patil * are met: 8*9207f9d2SChandrakanth patil * 9*9207f9d2SChandrakanth patil * 1. Redistributions of source code must retain the above copyright 10*9207f9d2SChandrakanth patil * notice, this list of conditions and the following disclaimer. 11*9207f9d2SChandrakanth patil * 2. Redistributions in binary form must reproduce the above copyright 12*9207f9d2SChandrakanth patil * notice, this list of conditions and the following disclaimer in 13*9207f9d2SChandrakanth patil * the documentation and/or other materials provided with the 14*9207f9d2SChandrakanth patil * distribution. 15*9207f9d2SChandrakanth patil * 16*9207f9d2SChandrakanth patil * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' 17*9207f9d2SChandrakanth patil * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 18*9207f9d2SChandrakanth patil * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 19*9207f9d2SChandrakanth patil * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS 20*9207f9d2SChandrakanth patil * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21*9207f9d2SChandrakanth patil * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22*9207f9d2SChandrakanth patil * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23*9207f9d2SChandrakanth patil * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24*9207f9d2SChandrakanth patil * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25*9207f9d2SChandrakanth patil * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26*9207f9d2SChandrakanth patil * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27*9207f9d2SChandrakanth patil * 28*9207f9d2SChandrakanth patil */ 29*9207f9d2SChandrakanth patil 30*9207f9d2SChandrakanth patil #ifndef __BNXT_RE_MAIN_H__ 31*9207f9d2SChandrakanth patil #define __BNXT_RE_MAIN_H__ 32*9207f9d2SChandrakanth patil 33*9207f9d2SChandrakanth patil #include <sys/param.h> 34*9207f9d2SChandrakanth patil #include <sys/queue.h> 35*9207f9d2SChandrakanth patil 36*9207f9d2SChandrakanth patil #include <infiniband/driver.h> 37*9207f9d2SChandrakanth patil #include <infiniband/endian.h> 38*9207f9d2SChandrakanth patil #include <infiniband/udma_barrier.h> 39*9207f9d2SChandrakanth patil 40*9207f9d2SChandrakanth patil #include <inttypes.h> 41*9207f9d2SChandrakanth patil #include <math.h> 42*9207f9d2SChandrakanth patil #include <pthread.h> 43*9207f9d2SChandrakanth patil #include <stdatomic.h> 44*9207f9d2SChandrakanth patil #include <stdbool.h> 45*9207f9d2SChandrakanth patil #include <stddef.h> 46*9207f9d2SChandrakanth patil #include <stdio.h> 47*9207f9d2SChandrakanth patil #include <stdlib.h> 48*9207f9d2SChandrakanth patil 49*9207f9d2SChandrakanth patil #include "abi.h" 50*9207f9d2SChandrakanth patil #include "list.h" 51*9207f9d2SChandrakanth patil #include "memory.h" 52*9207f9d2SChandrakanth patil 53*9207f9d2SChandrakanth patil #define DEV "bnxt_re : " 54*9207f9d2SChandrakanth patil #define BNXT_RE_UD_QP_STALL 0x400000 55*9207f9d2SChandrakanth patil 56*9207f9d2SChandrakanth patil #define CHIP_NUM_57508 0x1750 57*9207f9d2SChandrakanth patil #define CHIP_NUM_57504 0x1751 58*9207f9d2SChandrakanth patil #define CHIP_NUM_57502 0x1752 59*9207f9d2SChandrakanth patil #define CHIP_NUM_58818 0xd818 60*9207f9d2SChandrakanth patil #define CHIP_NUM_57608 0x1760 61*9207f9d2SChandrakanth patil 62*9207f9d2SChandrakanth patil #define BNXT_NSEC_PER_SEC 1000000000UL 63*9207f9d2SChandrakanth patil 64*9207f9d2SChandrakanth patil struct bnxt_re_chip_ctx { 65*9207f9d2SChandrakanth patil __u16 chip_num; 66*9207f9d2SChandrakanth patil __u8 chip_rev; 67*9207f9d2SChandrakanth patil __u8 chip_metal; 68*9207f9d2SChandrakanth patil bool chip_is_gen_p5_thor2; 69*9207f9d2SChandrakanth patil }; 70*9207f9d2SChandrakanth patil 71*9207f9d2SChandrakanth patil #define BNXT_RE_MAP_WC 0x1000 72*9207f9d2SChandrakanth patil #define BNXT_RE_DBR_PAGE 0x2000 73*9207f9d2SChandrakanth patil #define BNXT_RE_DB_RECOVERY_PAGE 0x3000 74*9207f9d2SChandrakanth patil 75*9207f9d2SChandrakanth patil #define BNXT_RE_DB_REPLAY_YIELD_CNT 256 76*9207f9d2SChandrakanth patil #define BNXT_RE_DB_KEY_INVALID -1 77*9207f9d2SChandrakanth patil #define BNXT_RE_MAX_DO_PACING 0xFFFF 78*9207f9d2SChandrakanth patil #define bnxt_re_wm_barrier() udma_to_device_barrier() 79*9207f9d2SChandrakanth patil #define unlikely(x) __builtin_expect(!!(x), 0) 80*9207f9d2SChandrakanth patil #define likely(x) __builtin_expect(!!(x), 1) 81*9207f9d2SChandrakanth patil 82*9207f9d2SChandrakanth patil #define CNA(v, d) \ 83*9207f9d2SChandrakanth patil { .vendor = PCI_VENDOR_ID_##v, \ 84*9207f9d2SChandrakanth patil .device = d } 85*9207f9d2SChandrakanth patil #define BNXT_RE_DEFINE_CNA_TABLE(_name) \ 86*9207f9d2SChandrakanth patil static const struct { \ 87*9207f9d2SChandrakanth patil unsigned vendor; \ 88*9207f9d2SChandrakanth patil unsigned device; \ 89*9207f9d2SChandrakanth patil } _name[] 90*9207f9d2SChandrakanth patil 91*9207f9d2SChandrakanth patil struct bnxt_re_dpi { 92*9207f9d2SChandrakanth patil __u32 dpindx; 93*9207f9d2SChandrakanth patil __u32 wcdpi; 94*9207f9d2SChandrakanth patil __u64 *dbpage; 95*9207f9d2SChandrakanth patil __u64 *wcdbpg; 96*9207f9d2SChandrakanth patil }; 97*9207f9d2SChandrakanth patil 98*9207f9d2SChandrakanth patil struct bnxt_re_pd { 99*9207f9d2SChandrakanth patil struct ibv_pd ibvpd; 100*9207f9d2SChandrakanth patil uint32_t pdid; 101*9207f9d2SChandrakanth patil }; 102*9207f9d2SChandrakanth patil 103*9207f9d2SChandrakanth patil struct xorshift32_state { 104*9207f9d2SChandrakanth patil uint32_t seed; 105*9207f9d2SChandrakanth patil }; 106*9207f9d2SChandrakanth patil 107*9207f9d2SChandrakanth patil struct bnxt_re_cq { 108*9207f9d2SChandrakanth patil struct ibv_cq ibvcq; 109*9207f9d2SChandrakanth patil struct bnxt_re_list_head sfhead; 110*9207f9d2SChandrakanth patil struct bnxt_re_list_head rfhead; 111*9207f9d2SChandrakanth patil struct bnxt_re_list_head prev_cq_head; 112*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx; 113*9207f9d2SChandrakanth patil struct bnxt_re_queue *cqq; 114*9207f9d2SChandrakanth patil struct bnxt_re_dpi *udpi; 115*9207f9d2SChandrakanth patil struct bnxt_re_mem *resize_mem; 116*9207f9d2SChandrakanth patil struct bnxt_re_mem *mem; 117*9207f9d2SChandrakanth patil struct bnxt_re_list_node dbnode; 118*9207f9d2SChandrakanth patil uint64_t shadow_db_key; 119*9207f9d2SChandrakanth patil uint32_t cqe_sz; 120*9207f9d2SChandrakanth patil uint32_t cqid; 121*9207f9d2SChandrakanth patil struct xorshift32_state rand; 122*9207f9d2SChandrakanth patil int deferred_arm_flags; 123*9207f9d2SChandrakanth patil bool first_arm; 124*9207f9d2SChandrakanth patil bool deferred_arm; 125*9207f9d2SChandrakanth patil bool phase; 126*9207f9d2SChandrakanth patil uint8_t dbr_lock; 127*9207f9d2SChandrakanth patil void *cq_page; 128*9207f9d2SChandrakanth patil }; 129*9207f9d2SChandrakanth patil 130*9207f9d2SChandrakanth patil struct bnxt_re_push_buffer { 131*9207f9d2SChandrakanth patil __u64 *pbuf; /*push wc buffer */ 132*9207f9d2SChandrakanth patil __u64 *wqe; /* hwqe addresses */ 133*9207f9d2SChandrakanth patil __u64 *ucdb; 134*9207f9d2SChandrakanth patil uint32_t st_idx; 135*9207f9d2SChandrakanth patil uint32_t qpid; 136*9207f9d2SChandrakanth patil uint16_t wcdpi; 137*9207f9d2SChandrakanth patil uint16_t nbit; 138*9207f9d2SChandrakanth patil uint32_t tail; 139*9207f9d2SChandrakanth patil }; 140*9207f9d2SChandrakanth patil 141*9207f9d2SChandrakanth patil enum bnxt_re_push_info_mask { 142*9207f9d2SChandrakanth patil BNXT_RE_PUSH_SIZE_MASK = 0x1FUL, 143*9207f9d2SChandrakanth patil BNXT_RE_PUSH_SIZE_SHIFT = 0x18UL 144*9207f9d2SChandrakanth patil }; 145*9207f9d2SChandrakanth patil 146*9207f9d2SChandrakanth patil struct bnxt_re_db_ppp_hdr { 147*9207f9d2SChandrakanth patil struct bnxt_re_db_hdr db_hdr; 148*9207f9d2SChandrakanth patil __u64 rsv_psz_pidx; 149*9207f9d2SChandrakanth patil }; 150*9207f9d2SChandrakanth patil 151*9207f9d2SChandrakanth patil struct bnxt_re_push_rec { 152*9207f9d2SChandrakanth patil struct bnxt_re_dpi *udpi; 153*9207f9d2SChandrakanth patil struct bnxt_re_push_buffer *pbuf; 154*9207f9d2SChandrakanth patil __u32 pbmap; /* only 16 bits in use */ 155*9207f9d2SChandrakanth patil }; 156*9207f9d2SChandrakanth patil 157*9207f9d2SChandrakanth patil struct bnxt_re_wrid { 158*9207f9d2SChandrakanth patil uint64_t wrid; 159*9207f9d2SChandrakanth patil int next_idx; 160*9207f9d2SChandrakanth patil uint32_t bytes; 161*9207f9d2SChandrakanth patil uint8_t sig; 162*9207f9d2SChandrakanth patil uint8_t slots; 163*9207f9d2SChandrakanth patil uint8_t wc_opcd; 164*9207f9d2SChandrakanth patil }; 165*9207f9d2SChandrakanth patil 166*9207f9d2SChandrakanth patil struct bnxt_re_qpcap { 167*9207f9d2SChandrakanth patil uint32_t max_swr; 168*9207f9d2SChandrakanth patil uint32_t max_rwr; 169*9207f9d2SChandrakanth patil uint32_t max_ssge; 170*9207f9d2SChandrakanth patil uint32_t max_rsge; 171*9207f9d2SChandrakanth patil uint32_t max_inline; 172*9207f9d2SChandrakanth patil uint8_t sqsig; 173*9207f9d2SChandrakanth patil uint8_t is_atomic_cap; 174*9207f9d2SChandrakanth patil }; 175*9207f9d2SChandrakanth patil 176*9207f9d2SChandrakanth patil struct bnxt_re_srq { 177*9207f9d2SChandrakanth patil struct ibv_srq ibvsrq; 178*9207f9d2SChandrakanth patil struct ibv_srq_attr cap; 179*9207f9d2SChandrakanth patil uint32_t srqid; 180*9207f9d2SChandrakanth patil struct bnxt_re_context *uctx; 181*9207f9d2SChandrakanth patil struct bnxt_re_queue *srqq; 182*9207f9d2SChandrakanth patil struct bnxt_re_wrid *srwrid; 183*9207f9d2SChandrakanth patil struct bnxt_re_dpi *udpi; 184*9207f9d2SChandrakanth patil struct bnxt_re_mem *mem; 185*9207f9d2SChandrakanth patil int start_idx; 186*9207f9d2SChandrakanth patil int last_idx; 187*9207f9d2SChandrakanth patil struct bnxt_re_list_node dbnode; 188*9207f9d2SChandrakanth patil uint64_t shadow_db_key; 189*9207f9d2SChandrakanth patil struct xorshift32_state rand; 190*9207f9d2SChandrakanth patil uint8_t dbr_lock; 191*9207f9d2SChandrakanth patil bool arm_req; 192*9207f9d2SChandrakanth patil }; 193*9207f9d2SChandrakanth patil 194*9207f9d2SChandrakanth patil struct bnxt_re_joint_queue { 195*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx; 196*9207f9d2SChandrakanth patil struct bnxt_re_queue *hwque; 197*9207f9d2SChandrakanth patil struct bnxt_re_wrid *swque; 198*9207f9d2SChandrakanth patil uint32_t start_idx; 199*9207f9d2SChandrakanth patil uint32_t last_idx; 200*9207f9d2SChandrakanth patil }; 201*9207f9d2SChandrakanth patil 202*9207f9d2SChandrakanth patil struct bnxt_re_qp { 203*9207f9d2SChandrakanth patil struct ibv_qp ibvqp; 204*9207f9d2SChandrakanth patil struct bnxt_re_qpcap cap; 205*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx; 206*9207f9d2SChandrakanth patil struct bnxt_re_chip_ctx *cctx; 207*9207f9d2SChandrakanth patil struct bnxt_re_joint_queue *jsqq; 208*9207f9d2SChandrakanth patil struct bnxt_re_joint_queue *jrqq; 209*9207f9d2SChandrakanth patil struct bnxt_re_dpi *udpi; 210*9207f9d2SChandrakanth patil uint64_t wqe_cnt; 211*9207f9d2SChandrakanth patil uint16_t mtu; 212*9207f9d2SChandrakanth patil uint16_t qpst; 213*9207f9d2SChandrakanth patil uint8_t qptyp; 214*9207f9d2SChandrakanth patil uint8_t qpmode; 215*9207f9d2SChandrakanth patil uint8_t push_st_en; 216*9207f9d2SChandrakanth patil uint8_t ppp_idx; 217*9207f9d2SChandrakanth patil uint32_t sq_psn; 218*9207f9d2SChandrakanth patil uint32_t sq_msn; 219*9207f9d2SChandrakanth patil uint32_t qpid; 220*9207f9d2SChandrakanth patil uint16_t max_push_sz; 221*9207f9d2SChandrakanth patil uint8_t sq_dbr_lock; 222*9207f9d2SChandrakanth patil uint8_t rq_dbr_lock; 223*9207f9d2SChandrakanth patil struct xorshift32_state rand; 224*9207f9d2SChandrakanth patil struct bnxt_re_list_node snode; 225*9207f9d2SChandrakanth patil struct bnxt_re_list_node rnode; 226*9207f9d2SChandrakanth patil struct bnxt_re_srq *srq; 227*9207f9d2SChandrakanth patil struct bnxt_re_cq *rcq; 228*9207f9d2SChandrakanth patil struct bnxt_re_cq *scq; 229*9207f9d2SChandrakanth patil struct bnxt_re_mem *mem;/* at cl 6 */ 230*9207f9d2SChandrakanth patil struct bnxt_re_list_node dbnode; 231*9207f9d2SChandrakanth patil uint64_t sq_shadow_db_key; 232*9207f9d2SChandrakanth patil uint64_t rq_shadow_db_key; 233*9207f9d2SChandrakanth patil }; 234*9207f9d2SChandrakanth patil 235*9207f9d2SChandrakanth patil struct bnxt_re_mr { 236*9207f9d2SChandrakanth patil struct ibv_mr vmr; 237*9207f9d2SChandrakanth patil }; 238*9207f9d2SChandrakanth patil 239*9207f9d2SChandrakanth patil struct bnxt_re_ah { 240*9207f9d2SChandrakanth patil struct ibv_ah ibvah; 241*9207f9d2SChandrakanth patil struct bnxt_re_pd *pd; 242*9207f9d2SChandrakanth patil uint32_t avid; 243*9207f9d2SChandrakanth patil }; 244*9207f9d2SChandrakanth patil 245*9207f9d2SChandrakanth patil struct bnxt_re_dev { 246*9207f9d2SChandrakanth patil struct verbs_device vdev; 247*9207f9d2SChandrakanth patil struct ibv_device_attr devattr; 248*9207f9d2SChandrakanth patil uint32_t pg_size; 249*9207f9d2SChandrakanth patil uint32_t cqe_size; 250*9207f9d2SChandrakanth patil uint32_t max_cq_depth; 251*9207f9d2SChandrakanth patil uint8_t abi_version; 252*9207f9d2SChandrakanth patil }; 253*9207f9d2SChandrakanth patil 254*9207f9d2SChandrakanth patil struct bnxt_re_res_list { 255*9207f9d2SChandrakanth patil struct bnxt_re_list_head head; 256*9207f9d2SChandrakanth patil pthread_spinlock_t lock; 257*9207f9d2SChandrakanth patil }; 258*9207f9d2SChandrakanth patil 259*9207f9d2SChandrakanth patil struct bnxt_re_context { 260*9207f9d2SChandrakanth patil struct ibv_context ibvctx; 261*9207f9d2SChandrakanth patil struct bnxt_re_dev *rdev; 262*9207f9d2SChandrakanth patil struct bnxt_re_chip_ctx *cctx; 263*9207f9d2SChandrakanth patil uint64_t comp_mask; 264*9207f9d2SChandrakanth patil struct bnxt_re_dpi udpi; 265*9207f9d2SChandrakanth patil uint32_t dev_id; 266*9207f9d2SChandrakanth patil uint32_t max_qp; 267*9207f9d2SChandrakanth patil uint32_t max_srq; 268*9207f9d2SChandrakanth patil uint32_t modes; 269*9207f9d2SChandrakanth patil void *shpg; 270*9207f9d2SChandrakanth patil pthread_mutex_t shlock; 271*9207f9d2SChandrakanth patil struct bnxt_re_push_rec *pbrec; 272*9207f9d2SChandrakanth patil void *dbr_page; 273*9207f9d2SChandrakanth patil void *bar_map; 274*9207f9d2SChandrakanth patil struct bnxt_re_res_list qp_dbr_res; 275*9207f9d2SChandrakanth patil struct bnxt_re_res_list cq_dbr_res; 276*9207f9d2SChandrakanth patil struct bnxt_re_res_list srq_dbr_res; 277*9207f9d2SChandrakanth patil void *db_recovery_page; 278*9207f9d2SChandrakanth patil struct ibv_comp_channel *dbr_ev_chan; 279*9207f9d2SChandrakanth patil struct ibv_cq *dbr_cq; 280*9207f9d2SChandrakanth patil pthread_t dbr_thread; 281*9207f9d2SChandrakanth patil uint64_t replay_cnt; 282*9207f9d2SChandrakanth patil }; 283*9207f9d2SChandrakanth patil 284*9207f9d2SChandrakanth patil struct bnxt_re_pacing_data { 285*9207f9d2SChandrakanth patil uint32_t do_pacing; 286*9207f9d2SChandrakanth patil uint32_t pacing_th; 287*9207f9d2SChandrakanth patil uint32_t dev_err_state; 288*9207f9d2SChandrakanth patil uint32_t alarm_th; 289*9207f9d2SChandrakanth patil }; 290*9207f9d2SChandrakanth patil 291*9207f9d2SChandrakanth patil /* Chip context related functions */ 292*9207f9d2SChandrakanth patil bool _is_chip_gen_p5(struct bnxt_re_chip_ctx *cctx); 293*9207f9d2SChandrakanth patil bool _is_chip_a0(struct bnxt_re_chip_ctx *cctx); 294*9207f9d2SChandrakanth patil bool _is_chip_thor2(struct bnxt_re_chip_ctx *cctx); 295*9207f9d2SChandrakanth patil bool _is_chip_gen_p5_thor2(struct bnxt_re_chip_ctx *cctx); 296*9207f9d2SChandrakanth patil 297*9207f9d2SChandrakanth patil /* DB ring functions used internally*/ 298*9207f9d2SChandrakanth patil void bnxt_re_ring_rq_db(struct bnxt_re_qp *qp); 299*9207f9d2SChandrakanth patil void bnxt_re_ring_sq_db(struct bnxt_re_qp *qp); 300*9207f9d2SChandrakanth patil void bnxt_re_ring_srq_arm(struct bnxt_re_srq *srq); 301*9207f9d2SChandrakanth patil void bnxt_re_ring_srq_db(struct bnxt_re_srq *srq); 302*9207f9d2SChandrakanth patil void bnxt_re_ring_cq_db(struct bnxt_re_cq *cq); 303*9207f9d2SChandrakanth patil void bnxt_re_ring_cq_arm_db(struct bnxt_re_cq *cq, uint8_t aflag); 304*9207f9d2SChandrakanth patil 305*9207f9d2SChandrakanth patil void bnxt_re_ring_pstart_db(struct bnxt_re_qp *qp, 306*9207f9d2SChandrakanth patil struct bnxt_re_push_buffer *pbuf); 307*9207f9d2SChandrakanth patil void bnxt_re_ring_pend_db(struct bnxt_re_qp *qp, 308*9207f9d2SChandrakanth patil struct bnxt_re_push_buffer *pbuf); 309*9207f9d2SChandrakanth patil void bnxt_re_fill_push_wcb(struct bnxt_re_qp *qp, 310*9207f9d2SChandrakanth patil struct bnxt_re_push_buffer *pbuf, 311*9207f9d2SChandrakanth patil uint32_t idx); 312*9207f9d2SChandrakanth patil 313*9207f9d2SChandrakanth patil void bnxt_re_fill_ppp(struct bnxt_re_push_buffer *pbuf, 314*9207f9d2SChandrakanth patil struct bnxt_re_qp *qp, uint8_t len, uint32_t idx); 315*9207f9d2SChandrakanth patil int bnxt_re_init_pbuf_list(struct bnxt_re_context *cntx); 316*9207f9d2SChandrakanth patil void bnxt_re_destroy_pbuf_list(struct bnxt_re_context *cntx); 317*9207f9d2SChandrakanth patil struct bnxt_re_push_buffer *bnxt_re_get_pbuf(uint8_t *push_st_en, 318*9207f9d2SChandrakanth patil uint8_t ppp_idx, 319*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx); 320*9207f9d2SChandrakanth patil void bnxt_re_put_pbuf(struct bnxt_re_context *cntx, 321*9207f9d2SChandrakanth patil struct bnxt_re_push_buffer *pbuf); 322*9207f9d2SChandrakanth patil 323*9207f9d2SChandrakanth patil void bnxt_re_db_recovery(struct bnxt_re_context *cntx); 324*9207f9d2SChandrakanth patil void *bnxt_re_dbr_thread(void *arg); 325*9207f9d2SChandrakanth patil bool _is_db_drop_recovery_enable(struct bnxt_re_context *cntx); 326*9207f9d2SChandrakanth patil int bnxt_re_poll_kernel_cq(struct bnxt_re_cq *cq); 327*9207f9d2SChandrakanth patil extern int bnxt_single_threaded; 328*9207f9d2SChandrakanth patil extern int bnxt_dyn_debug; 329*9207f9d2SChandrakanth patil 330*9207f9d2SChandrakanth patil #define bnxt_re_trace(fmt, ...) \ 331*9207f9d2SChandrakanth patil { \ 332*9207f9d2SChandrakanth patil if (bnxt_dyn_debug) \ 333*9207f9d2SChandrakanth patil fprintf(stderr, fmt, ##__VA_ARGS__); \ 334*9207f9d2SChandrakanth patil } 335*9207f9d2SChandrakanth patil 336*9207f9d2SChandrakanth patil /* pointer conversion functions*/ 337*9207f9d2SChandrakanth patil static inline struct bnxt_re_dev *to_bnxt_re_dev(struct ibv_device *ibvdev) 338*9207f9d2SChandrakanth patil { 339*9207f9d2SChandrakanth patil return container_of(ibvdev, struct bnxt_re_dev, vdev); 340*9207f9d2SChandrakanth patil } 341*9207f9d2SChandrakanth patil 342*9207f9d2SChandrakanth patil static inline struct bnxt_re_context *to_bnxt_re_context( 343*9207f9d2SChandrakanth patil struct ibv_context *ibvctx) 344*9207f9d2SChandrakanth patil { 345*9207f9d2SChandrakanth patil return container_of(ibvctx, struct bnxt_re_context, ibvctx); 346*9207f9d2SChandrakanth patil } 347*9207f9d2SChandrakanth patil 348*9207f9d2SChandrakanth patil static inline struct bnxt_re_pd *to_bnxt_re_pd(struct ibv_pd *ibvpd) 349*9207f9d2SChandrakanth patil { 350*9207f9d2SChandrakanth patil return container_of(ibvpd, struct bnxt_re_pd, ibvpd); 351*9207f9d2SChandrakanth patil } 352*9207f9d2SChandrakanth patil 353*9207f9d2SChandrakanth patil static inline struct bnxt_re_cq *to_bnxt_re_cq(struct ibv_cq *ibvcq) 354*9207f9d2SChandrakanth patil { 355*9207f9d2SChandrakanth patil return container_of(ibvcq, struct bnxt_re_cq, ibvcq); 356*9207f9d2SChandrakanth patil } 357*9207f9d2SChandrakanth patil 358*9207f9d2SChandrakanth patil static inline struct bnxt_re_qp *to_bnxt_re_qp(struct ibv_qp *ibvqp) 359*9207f9d2SChandrakanth patil { 360*9207f9d2SChandrakanth patil return container_of(ibvqp, struct bnxt_re_qp, ibvqp); 361*9207f9d2SChandrakanth patil } 362*9207f9d2SChandrakanth patil 363*9207f9d2SChandrakanth patil static inline struct bnxt_re_srq *to_bnxt_re_srq(struct ibv_srq *ibvsrq) 364*9207f9d2SChandrakanth patil { 365*9207f9d2SChandrakanth patil return container_of(ibvsrq, struct bnxt_re_srq, ibvsrq); 366*9207f9d2SChandrakanth patil } 367*9207f9d2SChandrakanth patil 368*9207f9d2SChandrakanth patil static inline struct bnxt_re_ah *to_bnxt_re_ah(struct ibv_ah *ibvah) 369*9207f9d2SChandrakanth patil { 370*9207f9d2SChandrakanth patil return container_of(ibvah, struct bnxt_re_ah, ibvah); 371*9207f9d2SChandrakanth patil } 372*9207f9d2SChandrakanth patil 373*9207f9d2SChandrakanth patil /* CQE manipulations */ 374*9207f9d2SChandrakanth patil #define bnxt_re_get_cqe_sz() (sizeof(struct bnxt_re_req_cqe) + \ 375*9207f9d2SChandrakanth patil sizeof(struct bnxt_re_bcqe)) 376*9207f9d2SChandrakanth patil #define bnxt_re_get_sqe_hdr_sz() (sizeof(struct bnxt_re_bsqe) + \ 377*9207f9d2SChandrakanth patil sizeof(struct bnxt_re_send)) 378*9207f9d2SChandrakanth patil #define bnxt_re_get_srqe_hdr_sz() (sizeof(struct bnxt_re_brqe) + \ 379*9207f9d2SChandrakanth patil sizeof(struct bnxt_re_srqe)) 380*9207f9d2SChandrakanth patil #define bnxt_re_get_srqe_sz() (sizeof(struct bnxt_re_brqe) + \ 381*9207f9d2SChandrakanth patil sizeof(struct bnxt_re_srqe) + \ 382*9207f9d2SChandrakanth patil BNXT_RE_MAX_INLINE_SIZE) 383*9207f9d2SChandrakanth patil #define bnxt_re_is_cqe_valid(valid, phase) \ 384*9207f9d2SChandrakanth patil (((valid) & BNXT_RE_BCQE_PH_MASK) == (phase)) 385*9207f9d2SChandrakanth patil 386*9207f9d2SChandrakanth patil static inline void bnxt_re_change_cq_phase(struct bnxt_re_cq *cq) 387*9207f9d2SChandrakanth patil { 388*9207f9d2SChandrakanth patil if (!cq->cqq->head) 389*9207f9d2SChandrakanth patil cq->phase = !(cq->phase & BNXT_RE_BCQE_PH_MASK); 390*9207f9d2SChandrakanth patil } 391*9207f9d2SChandrakanth patil 392*9207f9d2SChandrakanth patil static inline void *bnxt_re_get_swqe(struct bnxt_re_joint_queue *jqq, 393*9207f9d2SChandrakanth patil uint32_t *wqe_idx) 394*9207f9d2SChandrakanth patil { 395*9207f9d2SChandrakanth patil if (wqe_idx) 396*9207f9d2SChandrakanth patil *wqe_idx = jqq->start_idx; 397*9207f9d2SChandrakanth patil return &jqq->swque[jqq->start_idx]; 398*9207f9d2SChandrakanth patil } 399*9207f9d2SChandrakanth patil 400*9207f9d2SChandrakanth patil static inline void bnxt_re_jqq_mod_start(struct bnxt_re_joint_queue *jqq, 401*9207f9d2SChandrakanth patil uint32_t idx) 402*9207f9d2SChandrakanth patil { 403*9207f9d2SChandrakanth patil jqq->start_idx = jqq->swque[idx].next_idx; 404*9207f9d2SChandrakanth patil } 405*9207f9d2SChandrakanth patil 406*9207f9d2SChandrakanth patil static inline void bnxt_re_jqq_mod_last(struct bnxt_re_joint_queue *jqq, 407*9207f9d2SChandrakanth patil uint32_t idx) 408*9207f9d2SChandrakanth patil { 409*9207f9d2SChandrakanth patil jqq->last_idx = jqq->swque[idx].next_idx; 410*9207f9d2SChandrakanth patil } 411*9207f9d2SChandrakanth patil 412*9207f9d2SChandrakanth patil static inline uint32_t bnxt_re_init_depth(uint32_t ent, uint64_t cmask) 413*9207f9d2SChandrakanth patil { 414*9207f9d2SChandrakanth patil return cmask & BNXT_RE_COMP_MASK_UCNTX_POW2_DISABLED ? 415*9207f9d2SChandrakanth patil ent : roundup_pow_of_two(ent); 416*9207f9d2SChandrakanth patil } 417*9207f9d2SChandrakanth patil 418*9207f9d2SChandrakanth patil static inline uint32_t bnxt_re_get_diff(uint64_t cmask) 419*9207f9d2SChandrakanth patil { 420*9207f9d2SChandrakanth patil return cmask & BNXT_RE_COMP_MASK_UCNTX_RSVD_WQE_DISABLED ? 421*9207f9d2SChandrakanth patil 0 : BNXT_RE_FULL_FLAG_DELTA; 422*9207f9d2SChandrakanth patil } 423*9207f9d2SChandrakanth patil 424*9207f9d2SChandrakanth patil static inline int bnxt_re_calc_wqe_sz(int nsge) 425*9207f9d2SChandrakanth patil { 426*9207f9d2SChandrakanth patil /* This is used for both sq and rq. In case hdr size differs 427*9207f9d2SChandrakanth patil * in future move to individual functions. 428*9207f9d2SChandrakanth patil */ 429*9207f9d2SChandrakanth patil return sizeof(struct bnxt_re_sge) * nsge + bnxt_re_get_sqe_hdr_sz(); 430*9207f9d2SChandrakanth patil } 431*9207f9d2SChandrakanth patil 432*9207f9d2SChandrakanth patil /* Helper function to copy to push buffers */ 433*9207f9d2SChandrakanth patil static inline void bnxt_re_copy_data_to_pb(struct bnxt_re_push_buffer *pbuf, 434*9207f9d2SChandrakanth patil uint8_t offset, uint32_t idx) 435*9207f9d2SChandrakanth patil { 436*9207f9d2SChandrakanth patil __u64 *src; 437*9207f9d2SChandrakanth patil __u64 *dst; 438*9207f9d2SChandrakanth patil int indx; 439*9207f9d2SChandrakanth patil 440*9207f9d2SChandrakanth patil for (indx = 0; indx < idx; indx++) { 441*9207f9d2SChandrakanth patil dst = (__u64 *)(pbuf->pbuf + 2 * (indx + offset)); 442*9207f9d2SChandrakanth patil src = (__u64 *)pbuf->wqe[indx]; 443*9207f9d2SChandrakanth patil iowrite64(dst, *src); 444*9207f9d2SChandrakanth patil 445*9207f9d2SChandrakanth patil dst++; 446*9207f9d2SChandrakanth patil src++; 447*9207f9d2SChandrakanth patil iowrite64(dst, *src); 448*9207f9d2SChandrakanth patil } 449*9207f9d2SChandrakanth patil } 450*9207f9d2SChandrakanth patil 451*9207f9d2SChandrakanth patil static inline int bnxt_re_dp_spin_init(struct bnxt_spinlock *lock, int pshared, int need_lock) 452*9207f9d2SChandrakanth patil { 453*9207f9d2SChandrakanth patil lock->in_use = 0; 454*9207f9d2SChandrakanth patil lock->need_lock = need_lock; 455*9207f9d2SChandrakanth patil return pthread_spin_init(&lock->lock, PTHREAD_PROCESS_PRIVATE); 456*9207f9d2SChandrakanth patil } 457*9207f9d2SChandrakanth patil 458*9207f9d2SChandrakanth patil static inline int bnxt_re_dp_spin_destroy(struct bnxt_spinlock *lock) 459*9207f9d2SChandrakanth patil { 460*9207f9d2SChandrakanth patil return pthread_spin_destroy(&lock->lock); 461*9207f9d2SChandrakanth patil } 462*9207f9d2SChandrakanth patil 463*9207f9d2SChandrakanth patil static inline int bnxt_spin_lock(struct bnxt_spinlock *lock) 464*9207f9d2SChandrakanth patil { 465*9207f9d2SChandrakanth patil if (lock->need_lock) 466*9207f9d2SChandrakanth patil return pthread_spin_lock(&lock->lock); 467*9207f9d2SChandrakanth patil 468*9207f9d2SChandrakanth patil if (unlikely(lock->in_use)) { 469*9207f9d2SChandrakanth patil fprintf(stderr, "*** ERROR: multithreading violation ***\n" 470*9207f9d2SChandrakanth patil "You are running a multithreaded application but\n" 471*9207f9d2SChandrakanth patil "you set BNXT_SINGLE_THREADED=1. Please unset it.\n"); 472*9207f9d2SChandrakanth patil abort(); 473*9207f9d2SChandrakanth patil } else { 474*9207f9d2SChandrakanth patil lock->in_use = 1; 475*9207f9d2SChandrakanth patil /* This fence is not at all correct, but it increases the */ 476*9207f9d2SChandrakanth patil /* chance that in_use is detected by another thread without */ 477*9207f9d2SChandrakanth patil /* much runtime cost. */ 478*9207f9d2SChandrakanth patil atomic_thread_fence(memory_order_acq_rel); 479*9207f9d2SChandrakanth patil } 480*9207f9d2SChandrakanth patil 481*9207f9d2SChandrakanth patil return 0; 482*9207f9d2SChandrakanth patil } 483*9207f9d2SChandrakanth patil 484*9207f9d2SChandrakanth patil static inline int bnxt_spin_unlock(struct bnxt_spinlock *lock) 485*9207f9d2SChandrakanth patil { 486*9207f9d2SChandrakanth patil if (lock->need_lock) 487*9207f9d2SChandrakanth patil return pthread_spin_unlock(&lock->lock); 488*9207f9d2SChandrakanth patil 489*9207f9d2SChandrakanth patil lock->in_use = 0; 490*9207f9d2SChandrakanth patil return 0; 491*9207f9d2SChandrakanth patil } 492*9207f9d2SChandrakanth patil 493*9207f9d2SChandrakanth patil static void timespec_sub(const struct timespec *a, const struct timespec *b, 494*9207f9d2SChandrakanth patil struct timespec *res) 495*9207f9d2SChandrakanth patil { 496*9207f9d2SChandrakanth patil res->tv_sec = a->tv_sec - b->tv_sec; 497*9207f9d2SChandrakanth patil res->tv_nsec = a->tv_nsec - b->tv_nsec; 498*9207f9d2SChandrakanth patil if (res->tv_nsec < 0) { 499*9207f9d2SChandrakanth patil res->tv_sec--; 500*9207f9d2SChandrakanth patil res->tv_nsec += BNXT_NSEC_PER_SEC; 501*9207f9d2SChandrakanth patil } 502*9207f9d2SChandrakanth patil } 503*9207f9d2SChandrakanth patil 504*9207f9d2SChandrakanth patil /* 505*9207f9d2SChandrakanth patil * Function waits in a busy loop for a given nano seconds 506*9207f9d2SChandrakanth patil * The maximum wait period allowed is less than one second 507*9207f9d2SChandrakanth patil */ 508*9207f9d2SChandrakanth patil static inline void bnxt_re_sub_sec_busy_wait(uint32_t nsec) 509*9207f9d2SChandrakanth patil { 510*9207f9d2SChandrakanth patil struct timespec start, cur, res; 511*9207f9d2SChandrakanth patil 512*9207f9d2SChandrakanth patil if (nsec >= BNXT_NSEC_PER_SEC) 513*9207f9d2SChandrakanth patil return; 514*9207f9d2SChandrakanth patil 515*9207f9d2SChandrakanth patil if (clock_gettime(CLOCK_REALTIME, &start)) { 516*9207f9d2SChandrakanth patil fprintf(stderr, "%s: failed to get time : %d", 517*9207f9d2SChandrakanth patil __func__, errno); 518*9207f9d2SChandrakanth patil return; 519*9207f9d2SChandrakanth patil } 520*9207f9d2SChandrakanth patil 521*9207f9d2SChandrakanth patil while (1) { 522*9207f9d2SChandrakanth patil if (clock_gettime(CLOCK_REALTIME, &cur)) { 523*9207f9d2SChandrakanth patil fprintf(stderr, "%s: failed to get time : %d", 524*9207f9d2SChandrakanth patil __func__, errno); 525*9207f9d2SChandrakanth patil return; 526*9207f9d2SChandrakanth patil } 527*9207f9d2SChandrakanth patil 528*9207f9d2SChandrakanth patil timespec_sub(&cur, &start, &res); 529*9207f9d2SChandrakanth patil if (res.tv_nsec >= nsec) 530*9207f9d2SChandrakanth patil break; 531*9207f9d2SChandrakanth patil } 532*9207f9d2SChandrakanth patil } 533*9207f9d2SChandrakanth patil 534*9207f9d2SChandrakanth patil #define BNXT_RE_HW_RETX(a) ((a)->comp_mask & BNXT_RE_COMP_MASK_UCNTX_HW_RETX_ENABLED) 535*9207f9d2SChandrakanth patil #define bnxt_re_dp_spin_lock(lock) bnxt_spin_lock(lock) 536*9207f9d2SChandrakanth patil #define bnxt_re_dp_spin_unlock(lock) bnxt_spin_unlock(lock) 537*9207f9d2SChandrakanth patil 538*9207f9d2SChandrakanth patil #endif 539