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 #include <sys/types.h> 31*9207f9d2SChandrakanth patil #include <sys/mman.h> 32*9207f9d2SChandrakanth patil #include <sys/stat.h> 33*9207f9d2SChandrakanth patil 34*9207f9d2SChandrakanth patil #include <errno.h> 35*9207f9d2SChandrakanth patil #include <fcntl.h> 36*9207f9d2SChandrakanth patil #include <pthread.h> 37*9207f9d2SChandrakanth patil #include <stdio.h> 38*9207f9d2SChandrakanth patil #include <stdlib.h> 39*9207f9d2SChandrakanth patil #include <string.h> 40*9207f9d2SChandrakanth patil #include <unistd.h> 41*9207f9d2SChandrakanth patil 42*9207f9d2SChandrakanth patil #include "abi.h" 43*9207f9d2SChandrakanth patil #include "main.h" 44*9207f9d2SChandrakanth patil #include "verbs.h" 45*9207f9d2SChandrakanth patil 46*9207f9d2SChandrakanth patil #define PCI_VENDOR_ID_BROADCOM 0x14E4 47*9207f9d2SChandrakanth patil 48*9207f9d2SChandrakanth patil BNXT_RE_DEFINE_CNA_TABLE(cna_table) = { 49*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1605), /* BCM57454 Stratus NPAR */ 50*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1606), /* BCM57454 Stratus VF */ 51*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1614), /* BCM57454 Stratus */ 52*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16C0), /* BCM57417 NPAR */ 53*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16C1), /* BMC57414 VF */ 54*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16CE), /* BMC57311 */ 55*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16CF), /* BMC57312 */ 56*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16D6), /* BMC57412*/ 57*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16D7), /* BMC57414 */ 58*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16D8), /* BMC57416 Cu */ 59*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16D9), /* BMC57417 Cu */ 60*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16DF), /* BMC57314 */ 61*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16E2), /* BMC57417 */ 62*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16E3), /* BMC57416 */ 63*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16E5), /* BMC57314 VF */ 64*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16EB), /* BCM57412 NPAR */ 65*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16ED), /* BCM57414 NPAR */ 66*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16EF), /* BCM57416 NPAR */ 67*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16F0), /* BCM58730 */ 68*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x16F1), /* BCM57452 Stratus Mezz */ 69*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1750), /* Chip num 57500 */ 70*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1751), /* BCM57504 Gen P5 */ 71*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1752), /* BCM57502 Gen P5 */ 72*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1760), /* BCM57608 Thor 2*/ 73*9207f9d2SChandrakanth patil CNA(BROADCOM, 0xD82E), /* BCM5760x TH2 VF */ 74*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1803), /* BCM57508 Gen P5 NPAR */ 75*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1804), /* BCM57504 Gen P5 NPAR */ 76*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1805), /* BCM57502 Gen P5 NPAR */ 77*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1807), /* BCM5750x Gen P5 VF */ 78*9207f9d2SChandrakanth patil CNA(BROADCOM, 0x1809), /* BCM5750x Gen P5 VF HV */ 79*9207f9d2SChandrakanth patil CNA(BROADCOM, 0xD800), /* BCM880xx SR VF */ 80*9207f9d2SChandrakanth patil CNA(BROADCOM, 0xD802), /* BCM58802 SR */ 81*9207f9d2SChandrakanth patil CNA(BROADCOM, 0xD804), /* BCM58804 SR */ 82*9207f9d2SChandrakanth patil CNA(BROADCOM, 0xD818) /* BCM58818 Gen P5 SR2 */ 83*9207f9d2SChandrakanth patil }; 84*9207f9d2SChandrakanth patil 85*9207f9d2SChandrakanth patil static struct ibv_context_ops bnxt_re_cntx_ops = { 86*9207f9d2SChandrakanth patil .query_device = bnxt_re_query_device, 87*9207f9d2SChandrakanth patil .query_port = bnxt_re_query_port, 88*9207f9d2SChandrakanth patil .alloc_pd = bnxt_re_alloc_pd, 89*9207f9d2SChandrakanth patil .dealloc_pd = bnxt_re_free_pd, 90*9207f9d2SChandrakanth patil .reg_mr = bnxt_re_reg_mr, 91*9207f9d2SChandrakanth patil .dereg_mr = bnxt_re_dereg_mr, 92*9207f9d2SChandrakanth patil .create_cq = bnxt_re_create_cq, 93*9207f9d2SChandrakanth patil .poll_cq = bnxt_re_poll_cq, 94*9207f9d2SChandrakanth patil .req_notify_cq = bnxt_re_arm_cq, 95*9207f9d2SChandrakanth patil .cq_event = bnxt_re_cq_event, 96*9207f9d2SChandrakanth patil .resize_cq = bnxt_re_resize_cq, 97*9207f9d2SChandrakanth patil .destroy_cq = bnxt_re_destroy_cq, 98*9207f9d2SChandrakanth patil .create_srq = bnxt_re_create_srq, 99*9207f9d2SChandrakanth patil .modify_srq = bnxt_re_modify_srq, 100*9207f9d2SChandrakanth patil .query_srq = bnxt_re_query_srq, 101*9207f9d2SChandrakanth patil .destroy_srq = bnxt_re_destroy_srq, 102*9207f9d2SChandrakanth patil .post_srq_recv = bnxt_re_post_srq_recv, 103*9207f9d2SChandrakanth patil .create_qp = bnxt_re_create_qp, 104*9207f9d2SChandrakanth patil .query_qp = bnxt_re_query_qp, 105*9207f9d2SChandrakanth patil .modify_qp = bnxt_re_modify_qp, 106*9207f9d2SChandrakanth patil .destroy_qp = bnxt_re_destroy_qp, 107*9207f9d2SChandrakanth patil .post_send = bnxt_re_post_send, 108*9207f9d2SChandrakanth patil .post_recv = bnxt_re_post_recv, 109*9207f9d2SChandrakanth patil .async_event = bnxt_re_async_event, 110*9207f9d2SChandrakanth patil .create_ah = bnxt_re_create_ah, 111*9207f9d2SChandrakanth patil .destroy_ah = bnxt_re_destroy_ah 112*9207f9d2SChandrakanth patil }; 113*9207f9d2SChandrakanth patil 114*9207f9d2SChandrakanth patil bool _is_chip_gen_p5(struct bnxt_re_chip_ctx *cctx) 115*9207f9d2SChandrakanth patil { 116*9207f9d2SChandrakanth patil return (cctx->chip_num == CHIP_NUM_57508 || 117*9207f9d2SChandrakanth patil cctx->chip_num == CHIP_NUM_57504 || 118*9207f9d2SChandrakanth patil cctx->chip_num == CHIP_NUM_57502); 119*9207f9d2SChandrakanth patil } 120*9207f9d2SChandrakanth patil 121*9207f9d2SChandrakanth patil bool _is_chip_a0(struct bnxt_re_chip_ctx *cctx) 122*9207f9d2SChandrakanth patil { 123*9207f9d2SChandrakanth patil return !cctx->chip_rev; 124*9207f9d2SChandrakanth patil } 125*9207f9d2SChandrakanth patil 126*9207f9d2SChandrakanth patil bool _is_chip_thor2(struct bnxt_re_chip_ctx *cctx) 127*9207f9d2SChandrakanth patil { 128*9207f9d2SChandrakanth patil return (cctx->chip_num == CHIP_NUM_58818 || 129*9207f9d2SChandrakanth patil cctx->chip_num == CHIP_NUM_57608); 130*9207f9d2SChandrakanth patil } 131*9207f9d2SChandrakanth patil 132*9207f9d2SChandrakanth patil bool _is_chip_gen_p5_thor2(struct bnxt_re_chip_ctx *cctx) 133*9207f9d2SChandrakanth patil { 134*9207f9d2SChandrakanth patil return(_is_chip_gen_p5(cctx) || _is_chip_thor2(cctx)); 135*9207f9d2SChandrakanth patil } 136*9207f9d2SChandrakanth patil 137*9207f9d2SChandrakanth patil bool _is_db_drop_recovery_enable(struct bnxt_re_context *cntx) 138*9207f9d2SChandrakanth patil { 139*9207f9d2SChandrakanth patil return cntx->comp_mask & BNXT_RE_COMP_MASK_UCNTX_DBR_RECOVERY_ENABLED; 140*9207f9d2SChandrakanth patil } 141*9207f9d2SChandrakanth patil 142*9207f9d2SChandrakanth patil /* Determine the env variable */ 143*9207f9d2SChandrakanth patil static int single_threaded_app(void) 144*9207f9d2SChandrakanth patil { 145*9207f9d2SChandrakanth patil char *env; 146*9207f9d2SChandrakanth patil 147*9207f9d2SChandrakanth patil env = getenv("BNXT_SINGLE_THREADED"); 148*9207f9d2SChandrakanth patil if (env) 149*9207f9d2SChandrakanth patil return strcmp(env, "1") ? 0 : 1; 150*9207f9d2SChandrakanth patil 151*9207f9d2SChandrakanth patil return 0; 152*9207f9d2SChandrakanth patil } 153*9207f9d2SChandrakanth patil 154*9207f9d2SChandrakanth patil static int enable_dynamic_debug(void) 155*9207f9d2SChandrakanth patil { 156*9207f9d2SChandrakanth patil char *env; 157*9207f9d2SChandrakanth patil 158*9207f9d2SChandrakanth patil env = getenv("BNXT_DYN_DBG"); 159*9207f9d2SChandrakanth patil if (env) 160*9207f9d2SChandrakanth patil return strcmp(env, "1") ? 0 : 1; 161*9207f9d2SChandrakanth patil 162*9207f9d2SChandrakanth patil return 0; 163*9207f9d2SChandrakanth patil } 164*9207f9d2SChandrakanth patil 165*9207f9d2SChandrakanth patil /* Static Context Init functions */ 166*9207f9d2SChandrakanth patil static int _bnxt_re_init_context(struct bnxt_re_dev *dev, 167*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx, 168*9207f9d2SChandrakanth patil struct bnxt_re_cntx_resp *resp, int cmd_fd) 169*9207f9d2SChandrakanth patil { 170*9207f9d2SChandrakanth patil bnxt_single_threaded = 0; 171*9207f9d2SChandrakanth patil cntx->cctx = malloc(sizeof(struct bnxt_re_chip_ctx)); 172*9207f9d2SChandrakanth patil if (!cntx->cctx) 173*9207f9d2SChandrakanth patil goto failed; 174*9207f9d2SChandrakanth patil 175*9207f9d2SChandrakanth patil if (BNXT_RE_ABI_VERSION >= 4) { 176*9207f9d2SChandrakanth patil cntx->cctx->chip_num = resp->chip_id0 & 0xFFFF; 177*9207f9d2SChandrakanth patil cntx->cctx->chip_rev = (resp->chip_id0 >> 178*9207f9d2SChandrakanth patil BNXT_RE_CHIP_ID0_CHIP_REV_SFT) & 0xFF; 179*9207f9d2SChandrakanth patil cntx->cctx->chip_metal = (resp->chip_id0 >> 180*9207f9d2SChandrakanth patil BNXT_RE_CHIP_ID0_CHIP_MET_SFT) & 181*9207f9d2SChandrakanth patil 0xFF; 182*9207f9d2SChandrakanth patil cntx->cctx->chip_is_gen_p5_thor2 = _is_chip_gen_p5_thor2(cntx->cctx); 183*9207f9d2SChandrakanth patil } 184*9207f9d2SChandrakanth patil if (BNXT_RE_ABI_VERSION != 4) { 185*9207f9d2SChandrakanth patil cntx->dev_id = resp->dev_id; 186*9207f9d2SChandrakanth patil cntx->max_qp = resp->max_qp; 187*9207f9d2SChandrakanth patil } 188*9207f9d2SChandrakanth patil 189*9207f9d2SChandrakanth patil if (BNXT_RE_ABI_VERSION > 5) 190*9207f9d2SChandrakanth patil cntx->modes = resp->modes; 191*9207f9d2SChandrakanth patil cntx->comp_mask = resp->comp_mask; 192*9207f9d2SChandrakanth patil dev->pg_size = resp->pg_size; 193*9207f9d2SChandrakanth patil dev->cqe_size = resp->cqe_size; 194*9207f9d2SChandrakanth patil dev->max_cq_depth = resp->max_cqd; 195*9207f9d2SChandrakanth patil 196*9207f9d2SChandrakanth patil /* mmap shared page. */ 197*9207f9d2SChandrakanth patil cntx->shpg = mmap(NULL, dev->pg_size, PROT_READ | PROT_WRITE, 198*9207f9d2SChandrakanth patil MAP_SHARED, cmd_fd, 0); 199*9207f9d2SChandrakanth patil if (cntx->shpg == MAP_FAILED) { 200*9207f9d2SChandrakanth patil cntx->shpg = NULL; 201*9207f9d2SChandrakanth patil goto free; 202*9207f9d2SChandrakanth patil } 203*9207f9d2SChandrakanth patil 204*9207f9d2SChandrakanth patil if (cntx->comp_mask & BNXT_RE_COMP_MASK_UCNTX_DBR_PACING_ENABLED) { 205*9207f9d2SChandrakanth patil cntx->dbr_page = mmap(NULL, dev->pg_size, PROT_READ, 206*9207f9d2SChandrakanth patil MAP_SHARED, cmd_fd, BNXT_RE_DBR_PAGE); 207*9207f9d2SChandrakanth patil if (cntx->dbr_page == MAP_FAILED) { 208*9207f9d2SChandrakanth patil munmap(cntx->shpg, dev->pg_size); 209*9207f9d2SChandrakanth patil cntx->shpg = NULL; 210*9207f9d2SChandrakanth patil cntx->dbr_page = NULL; 211*9207f9d2SChandrakanth patil goto free; 212*9207f9d2SChandrakanth patil } 213*9207f9d2SChandrakanth patil } 214*9207f9d2SChandrakanth patil 215*9207f9d2SChandrakanth patil /* check for ENV for single thread */ 216*9207f9d2SChandrakanth patil bnxt_single_threaded = single_threaded_app(); 217*9207f9d2SChandrakanth patil if (bnxt_single_threaded) 218*9207f9d2SChandrakanth patil fprintf(stderr, DEV " Running in Single threaded mode\n"); 219*9207f9d2SChandrakanth patil bnxt_dyn_debug = enable_dynamic_debug(); 220*9207f9d2SChandrakanth patil pthread_mutex_init(&cntx->shlock, NULL); 221*9207f9d2SChandrakanth patil 222*9207f9d2SChandrakanth patil return 0; 223*9207f9d2SChandrakanth patil 224*9207f9d2SChandrakanth patil free: 225*9207f9d2SChandrakanth patil free(cntx->cctx); 226*9207f9d2SChandrakanth patil failed: 227*9207f9d2SChandrakanth patil fprintf(stderr, DEV "Failed to initialize context for device\n"); 228*9207f9d2SChandrakanth patil return errno; 229*9207f9d2SChandrakanth patil } 230*9207f9d2SChandrakanth patil 231*9207f9d2SChandrakanth patil static void _bnxt_re_uninit_context(struct bnxt_re_dev *dev, 232*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx) 233*9207f9d2SChandrakanth patil { 234*9207f9d2SChandrakanth patil int ret; 235*9207f9d2SChandrakanth patil 236*9207f9d2SChandrakanth patil if (cntx->comp_mask & BNXT_RE_COMP_MASK_UCNTX_DBR_PACING_ENABLED) 237*9207f9d2SChandrakanth patil munmap(cntx->dbr_page, dev->pg_size); 238*9207f9d2SChandrakanth patil /* Unmap if anything device specific was 239*9207f9d2SChandrakanth patil * mapped in init_context. 240*9207f9d2SChandrakanth patil */ 241*9207f9d2SChandrakanth patil pthread_mutex_destroy(&cntx->shlock); 242*9207f9d2SChandrakanth patil if (cntx->shpg) 243*9207f9d2SChandrakanth patil munmap(cntx->shpg, dev->pg_size); 244*9207f9d2SChandrakanth patil 245*9207f9d2SChandrakanth patil /* Un-map DPI only for the first PD that was 246*9207f9d2SChandrakanth patil * allocated in this context. 247*9207f9d2SChandrakanth patil */ 248*9207f9d2SChandrakanth patil if (cntx->udpi.wcdbpg && cntx->udpi.wcdbpg != MAP_FAILED) { 249*9207f9d2SChandrakanth patil munmap(cntx->udpi.wcdbpg, dev->pg_size); 250*9207f9d2SChandrakanth patil cntx->udpi.wcdbpg = NULL; 251*9207f9d2SChandrakanth patil bnxt_re_destroy_pbuf_list(cntx); 252*9207f9d2SChandrakanth patil } 253*9207f9d2SChandrakanth patil 254*9207f9d2SChandrakanth patil if (cntx->udpi.dbpage && cntx->udpi.dbpage != MAP_FAILED) { 255*9207f9d2SChandrakanth patil munmap(cntx->udpi.dbpage, dev->pg_size); 256*9207f9d2SChandrakanth patil cntx->udpi.dbpage = NULL; 257*9207f9d2SChandrakanth patil } 258*9207f9d2SChandrakanth patil if (_is_db_drop_recovery_enable(cntx)) { 259*9207f9d2SChandrakanth patil if (cntx->dbr_cq) { 260*9207f9d2SChandrakanth patil ret = pthread_cancel(cntx->dbr_thread); 261*9207f9d2SChandrakanth patil if (ret) 262*9207f9d2SChandrakanth patil fprintf(stderr, DEV "pthread_cancel error %d\n", ret); 263*9207f9d2SChandrakanth patil 264*9207f9d2SChandrakanth patil if (cntx->db_recovery_page) 265*9207f9d2SChandrakanth patil munmap(cntx->db_recovery_page, dev->pg_size); 266*9207f9d2SChandrakanth patil ret = ibv_destroy_cq(cntx->dbr_cq); 267*9207f9d2SChandrakanth patil if (ret) 268*9207f9d2SChandrakanth patil fprintf(stderr, DEV "ibv_destroy_cq error %d\n", ret); 269*9207f9d2SChandrakanth patil } 270*9207f9d2SChandrakanth patil 271*9207f9d2SChandrakanth patil if (cntx->dbr_ev_chan) { 272*9207f9d2SChandrakanth patil ret = ibv_destroy_comp_channel(cntx->dbr_ev_chan); 273*9207f9d2SChandrakanth patil if (ret) 274*9207f9d2SChandrakanth patil fprintf(stderr, 275*9207f9d2SChandrakanth patil DEV "ibv_destroy_comp_channel error\n"); 276*9207f9d2SChandrakanth patil } 277*9207f9d2SChandrakanth patil pthread_spin_destroy(&cntx->qp_dbr_res.lock); 278*9207f9d2SChandrakanth patil pthread_spin_destroy(&cntx->cq_dbr_res.lock); 279*9207f9d2SChandrakanth patil pthread_spin_destroy(&cntx->srq_dbr_res.lock); 280*9207f9d2SChandrakanth patil } 281*9207f9d2SChandrakanth patil free(cntx->cctx); 282*9207f9d2SChandrakanth patil } 283*9207f9d2SChandrakanth patil 284*9207f9d2SChandrakanth patil /* Context Init functions */ 285*9207f9d2SChandrakanth patil int bnxt_re_init_context(struct verbs_device *vdev, struct ibv_context *ibvctx, 286*9207f9d2SChandrakanth patil int cmd_fd) 287*9207f9d2SChandrakanth patil { 288*9207f9d2SChandrakanth patil struct bnxt_re_cntx_resp resp = {}; 289*9207f9d2SChandrakanth patil struct bnxt_re_cntx_req req = {}; 290*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx; 291*9207f9d2SChandrakanth patil struct bnxt_re_dev *rdev; 292*9207f9d2SChandrakanth patil int ret = 0; 293*9207f9d2SChandrakanth patil 294*9207f9d2SChandrakanth patil rdev = to_bnxt_re_dev(&vdev->device); 295*9207f9d2SChandrakanth patil cntx = to_bnxt_re_context(ibvctx); 296*9207f9d2SChandrakanth patil ibvctx->cmd_fd = cmd_fd; 297*9207f9d2SChandrakanth patil 298*9207f9d2SChandrakanth patil req.comp_mask |= BNXT_RE_COMP_MASK_REQ_UCNTX_POW2_SUPPORT; 299*9207f9d2SChandrakanth patil req.comp_mask |= BNXT_RE_COMP_MASK_REQ_UCNTX_RSVD_WQE; 300*9207f9d2SChandrakanth patil ret = ibv_cmd_get_context(ibvctx, &req.cmd, sizeof(req), 301*9207f9d2SChandrakanth patil &resp.resp, sizeof(resp)); 302*9207f9d2SChandrakanth patil 303*9207f9d2SChandrakanth patil if (ret) { 304*9207f9d2SChandrakanth patil fprintf(stderr, DEV "Failed to get context for device, ret = 0x%x, errno %d\n", ret, errno); 305*9207f9d2SChandrakanth patil return errno; 306*9207f9d2SChandrakanth patil } 307*9207f9d2SChandrakanth patil 308*9207f9d2SChandrakanth patil ret = _bnxt_re_init_context(rdev, cntx, &resp, cmd_fd); 309*9207f9d2SChandrakanth patil if (!ret) 310*9207f9d2SChandrakanth patil ibvctx->ops = bnxt_re_cntx_ops; 311*9207f9d2SChandrakanth patil 312*9207f9d2SChandrakanth patil cntx->rdev = rdev; 313*9207f9d2SChandrakanth patil ret = bnxt_re_query_device_compat(&cntx->ibvctx, &rdev->devattr); 314*9207f9d2SChandrakanth patil 315*9207f9d2SChandrakanth patil return ret; 316*9207f9d2SChandrakanth patil } 317*9207f9d2SChandrakanth patil 318*9207f9d2SChandrakanth patil void bnxt_re_uninit_context(struct verbs_device *vdev, 319*9207f9d2SChandrakanth patil struct ibv_context *ibvctx) 320*9207f9d2SChandrakanth patil { 321*9207f9d2SChandrakanth patil struct bnxt_re_context *cntx; 322*9207f9d2SChandrakanth patil struct bnxt_re_dev *rdev; 323*9207f9d2SChandrakanth patil 324*9207f9d2SChandrakanth patil cntx = to_bnxt_re_context(ibvctx); 325*9207f9d2SChandrakanth patil rdev = cntx->rdev; 326*9207f9d2SChandrakanth patil _bnxt_re_uninit_context(rdev, cntx); 327*9207f9d2SChandrakanth patil } 328*9207f9d2SChandrakanth patil 329*9207f9d2SChandrakanth patil static struct verbs_device_ops bnxt_re_dev_ops = { 330*9207f9d2SChandrakanth patil .init_context = bnxt_re_init_context, 331*9207f9d2SChandrakanth patil .uninit_context = bnxt_re_uninit_context, 332*9207f9d2SChandrakanth patil }; 333*9207f9d2SChandrakanth patil 334*9207f9d2SChandrakanth patil static struct verbs_device *bnxt_re_driver_init(const char *uverbs_sys_path, 335*9207f9d2SChandrakanth patil int abi_version) 336*9207f9d2SChandrakanth patil { 337*9207f9d2SChandrakanth patil char value[10]; 338*9207f9d2SChandrakanth patil struct bnxt_re_dev *dev; 339*9207f9d2SChandrakanth patil unsigned vendor, device; 340*9207f9d2SChandrakanth patil int i; 341*9207f9d2SChandrakanth patil 342*9207f9d2SChandrakanth patil if (ibv_read_sysfs_file(uverbs_sys_path, "device/vendor", 343*9207f9d2SChandrakanth patil value, sizeof(value)) < 0) 344*9207f9d2SChandrakanth patil return NULL; 345*9207f9d2SChandrakanth patil vendor = strtol(value, NULL, 16); 346*9207f9d2SChandrakanth patil 347*9207f9d2SChandrakanth patil if (ibv_read_sysfs_file(uverbs_sys_path, "device/device", 348*9207f9d2SChandrakanth patil value, sizeof(value)) < 0) 349*9207f9d2SChandrakanth patil return NULL; 350*9207f9d2SChandrakanth patil device = strtol(value, NULL, 16); 351*9207f9d2SChandrakanth patil 352*9207f9d2SChandrakanth patil for (i = 0; i < sizeof(cna_table) / sizeof(cna_table[0]); ++i) 353*9207f9d2SChandrakanth patil if (vendor == cna_table[i].vendor && 354*9207f9d2SChandrakanth patil device == cna_table[i].device) 355*9207f9d2SChandrakanth patil goto found; 356*9207f9d2SChandrakanth patil return NULL; 357*9207f9d2SChandrakanth patil found: 358*9207f9d2SChandrakanth patil if (abi_version != BNXT_RE_ABI_VERSION) { 359*9207f9d2SChandrakanth patil fprintf(stderr, DEV "FATAL: Max supported ABI of %s is %d " 360*9207f9d2SChandrakanth patil "check for the latest version of kernel driver and" 361*9207f9d2SChandrakanth patil "user library\n", uverbs_sys_path, abi_version); 362*9207f9d2SChandrakanth patil return NULL; 363*9207f9d2SChandrakanth patil } 364*9207f9d2SChandrakanth patil 365*9207f9d2SChandrakanth patil dev = calloc(1, sizeof(*dev)); 366*9207f9d2SChandrakanth patil if (!dev) { 367*9207f9d2SChandrakanth patil fprintf(stderr, DEV "Failed to allocate device for %s\n", 368*9207f9d2SChandrakanth patil uverbs_sys_path); 369*9207f9d2SChandrakanth patil return NULL; 370*9207f9d2SChandrakanth patil } 371*9207f9d2SChandrakanth patil 372*9207f9d2SChandrakanth patil dev->vdev.sz = sizeof(*dev); 373*9207f9d2SChandrakanth patil dev->vdev.size_of_context = 374*9207f9d2SChandrakanth patil sizeof(struct bnxt_re_context) - sizeof(struct ibv_context); 375*9207f9d2SChandrakanth patil dev->vdev.ops = &bnxt_re_dev_ops; 376*9207f9d2SChandrakanth patil 377*9207f9d2SChandrakanth patil return &dev->vdev; 378*9207f9d2SChandrakanth patil } 379*9207f9d2SChandrakanth patil 380*9207f9d2SChandrakanth patil static __attribute__((constructor)) void bnxt_re_register_driver(void) 381*9207f9d2SChandrakanth patil { 382*9207f9d2SChandrakanth patil verbs_register_driver("bnxtre", bnxt_re_driver_init); 383*9207f9d2SChandrakanth patil } 384